2011-09-16 7 views
2

J'ai vraiment du mal à essayer d'obtenir une mise en page graphique décisive dans tkinter. Je vise la mise en page à gauche, mais n'a pas obtenu plus loin que la mise en page à droite:Comment appliquer une barre de défilement à un cadre dans un canevas

enter image description here enter image description here

Je me sens complètement perdu dans tout ce que les différents gestionnaires de mise en page. Ceci est mon code à ce jour:

from Tkinter import * 

class ScrolledCanvas: 
    def __init__(self, master, width=500, height=350): 
     Label(master, text="top of master frame").pack(side=TOP) 
     self.control=Frame(master) 
     self.control.pack(side=BOTTOM, fill=X, padx=2) 
     Label(self.control, text="bottom of master frame").pack() 
     self.grid = Frame(master, bd=2, bg="red") 
     self.canvas = Canvas(master, relief=SUNKEN, borderwidth=2, 
          scrollregion=('-11c', '-11c', '50c', '20c')) 
     self.vscroll = Scrollbar(master, command=self.canvas.yview) 
     self.canvas.configure(yscrollcommand=self.vscroll.set) 

     self.grid.pack(expand=YES, fill=BOTH, padx=1, pady=1) 
     self.grid.rowconfigure(0, weight=1, minsize=0) 
     self.grid.columnconfigure(0, weight=1, minsize=0) 

     self.canvas.grid(padx=1, in_=self.grid, pady=1, row=0, 
         column=0, rowspan=1, columnspan=1, sticky='news') 
     self.vscroll.grid(padx=1, in_=self.grid, pady=1, row=0, 
          column=1, rowspan=1, columnspan=1, sticky='news') 
     self.oldFill = None 
     self.canvas = self.fillCanvas(self.canvas) 

    def fillCanvas(self, theCanvas): 
     for i in range(10): 
      frame = Frame(theCanvas) 
      Label(frame, text="text for inner frame (%s)" % i).pack(side=TOP) 
      Button(frame, text="button %s.1" % i).pack(side=LEFT) 
      Button(frame, text="button %s.2" % i).pack(side=LEFT) 
      frame.pack() 
     return theCanvas 

if __name__ == '__main__': 
    root = Tk() 
    scroll = ScrolledCanvas(root) 
    root.mainloop() 

Pour une raison quelconque le scrollregion se développe en taille réelle, ce qui rend toutes les actions scrollbar obsolètes (Cette base de code sur un exemple scrollbar où la toile est rempli avec des rectangles, et tout défile vraiment agréable). J'ai probablement manqué quelque chose de fondamental sur le redimensionnement, car la plupart des composants semblent ignorer complètement leur largeur et leur hauteur fixes.

Je cherche de l'aide sur la façon d'obtenir cet exemple pour travailler avec tkinter. Je sais qu'il existe d'autres technologies de mise en page, et je sais que d'autres modules offrent des widgets défilants prêts à l'emploi. Mais à moins d'être absolument inévitable, j'aime vraiment m'en tenir à cet exemple, qui m'a coûté au moins 3 nuits jusqu'ici ...

+1

Je sais que c'est un peu vieux, mais vous pouvez regarder ceci: http://stackoverflow.com/questions/3085696/adding-a-scrollbar-to-a-grid-of-widgets-in- tkinter – samwyse

Répondre

4

Vous ne pouvez pas empaqueter (ou mettre en grille, ou placer) des widgets dans le canevas et attendre leur défilement. Au lieu de cela, vous devez utiliser la méthode create_window.

+0

Merci, c'était vraiment une révélation! Alors que cela permet à la toile de défiler comme je le souhaite, cela me laisse avec le nouveau problème que je dois placer les cadres manuellement sur la toile, ou est-ce que je me suis trompé? Dans mon application, le nombre et la taille des cadres varient, alors j'espérais pouvoir créer chaque image et laisser à un gestionnaire de disposition de les mettre les uns sur les autres ... Y at-il une chance que je puisse atteindre ce? (Je ne suis pas coincé avec le widget canvas, je cherche juste des combinaisons de widgets fonctionnelles pour obtenir la disposition désirée ...) –

+0

Oui, vous devez les positionner manuellement. Généralement, ce que je fais est de créer un cadre pour tout le contenu, et pack (ou grille, ou placer) le contenu dans ce cadre. Ensuite, je dois juste ajouter ce cadre à la toile. Cela devient très gérable de cette façon. Une autre astuce consiste à lier à l'événement '' de la toile - il sera déclenché chaque fois que le canevas est redimensionné. Vous pouvez ensuite utiliser les informations de cet événement pour redimensionner cette image afin qu'elle corresponde exactement à la largeur du canevas. –

+0

Merci encore, je vais le faire comme vous l'avez proposé. –

Questions connexes