[python][Tkinter] Scroller et class

Fermé
frites.saucisse - 14 sept. 2007 à 09:11
 frites.saucisse - 20 sept. 2007 à 07:48
Bonjour,

J'ai bricolé un exemple simplifié pour mettre en évidence le problème que j'ai dans mon application réelle.

J'ai une fenêtre principale de type Frame. Dedans il y a un Label (qui pourrait aussi être un Menu) et en dessous un Canvas (self.c). Une class que j'ai piqué sur effbot fait apparaître des barres de défilement verticales et horizontales lorsque la taille de la fenêtre est plus petite que le canvas self.c. A l'intérieur de ce dernier il y a un autre canvas (self.canvas) et encore un (self.truc) qui contient des widgets (en l'occurrence des boutons). Le problème est là: si self.truc est dans la class Fenetre_principale, tout marche bien. Les boutons restent cachés sous le canvas self.canvas (au 2è plan). Par contre si self.truc appelle une class qui contient les widgets, lorsqu'on actionne la barre de défilement, les boutons passent par dessus le Label tout en haut: ils sont comme au premier plan. Comment faire résoudre ce problème?

Tout cela fait beaucoup de texte pour une question que je n'espère pas trop triviale. En tout cas merci pour votre réponse.

from Tkinter import *

class AutoScrollbar(Scrollbar):
    def set(self, lo, hi):
        if float(lo) <= 0.0 and float(hi) >= 1.0:
            # grid_remove is currently missing from Tkinter!
            self.tk.call("grid", "remove", self)
        else:
            self.grid()
        Scrollbar.set(self, lo, hi)
    def pack(self, **kw):
        raise TclError, "cannot use pack with this widget"
    def place(self, **kw):
        raise TclError, "cannot use place with this widget"

#############################################################
class Test(Canvas):
    def __init__(self,boss):
        Canvas.__init__(self)

        for a in range(100):
            t=Button(self,text=str(a)+' Blablabla')
            t.grid(sticky=E+W)
        
#############################################################
class Fenetre_principale(Frame):
    """Constructeur fenêtre principale"""
    def __init__(self,boss=None):
        Frame.__init__(self)

        self.b=Label(self.master,text='Un label bien long pour qu''il puisse prendre au moins toute la largeur de la fenêtre')
        self.b.grid(row=0,column=0,sticky=E+W)

        self.c=Canvas(self.master)
        self.c.grid(row=1,column=0)

        self.vscrollbar = AutoScrollbar(self.c)
        self.vscrollbar.grid(row=1, column=1, sticky=N+S)
        self.hscrollbar = AutoScrollbar(self.c, orient=HORIZONTAL)
        self.hscrollbar.grid(row=2, column=0, sticky=E+W)

        self.canvas = Canvas(self.c,
                        yscrollcommand=self.vscrollbar.set,
                        xscrollcommand=self.hscrollbar.set)
        self.canvas.grid(row=1, column=0, sticky=N+S+E+W)

        self.vscrollbar.config(command=self.canvas.yview)
        self.hscrollbar.config(command=self.canvas.xview)

        self.c.grid_rowconfigure(1, weight=1)
        self.c.grid_columnconfigure(0, weight=1)

# Avec cette ligne le résultat n'est pas tel que voulu. 
        self.truc=Test(self.canvas)

# Avec cette solution, ça marche bien
#        self.truc=Canvas(self.canvas)

#        for a in range(100):
#            t=Button(self.truc,text=str(a)+' Blablabla')
#            t.grid(sticky=E+W)


        self.canvas.create_window(0, 0, anchor=NW, window=self.truc)
        self.truc.update_idletasks()
        self.canvas.config(scrollregion=self.canvas.bbox("all"))

if __name__=='__main__':
    
    Fenetre_principale().mainloop()

2 réponses

frites.saucisse
17 sept. 2007 à 08:13
Personne n'a d'idée pour ce problème?
J'ai entretemps essayé avec des option lower() mais sans résultat.
0
frites.saucisse
20 sept. 2007 à 07:48
Pour info

class Test(Canvas):
    def __init__(self,boss):
        Canvas.__init__(self,boss)

        for a in range(100):
            t=Button(self,text=str(a)+' Blablabla')
            t.grid(sticky=E+W)
0