2016-09-26 4 views
0

Was ich in Tkinter in Python wollen 2.7 ist das folgende Raster-Layout:Wie kommt man in Python Tkinter zu einem komplett sticky Raster von Treeview und Scrollbar?

Grid Layout

jedoch einmal, beginne ich die grid() Funktionen statt pack() Funktionen, nichts zeigt auf das Skript ausgeführt wird. Das Folgende ist, was ich bin fest:

import Tkinter, ttk 

class App(Tkinter.Frame): 
    def __init__(self,parent): 
     Tkinter.Frame.__init__(self, parent, relief=Tkinter.SUNKEN, bd=2) 
     self.parent = parent   
     self.grid(row=0, column=0, sticky="nsew") 
     self.menubar = Tkinter.Menu(self) 
     try: 
      self.parent.config(menu=self.menubar) 
     except AttributeError: 
      self.tk.call(self.parent, "config", "-menu", self.menubar)  

     self.tree = ttk.Treeview(self.parent) 
     self.tree.grid(row=0, column=0, sticky="nsew") 

     self.yscrollbar = ttk.Scrollbar(self, orient='vertical', command=self.tree.yview) 
     self.yscrollbar.grid(row=0, column=1, sticky='nse') 
     self.tree.configure(yscrollcommand=self.yscrollbar.set) 
     self.yscrollbar.configure(command=self.tree.yview) 

if __name__ == "__main__": 
    root = Tkinter.Tk() 
    root.title("MyApp") 
    app = App(root) 
    app.pack() 
    app.mainloop() 

Jede Hilfe wird sehr geschätzt werden.

Antwort

2

Sie haben mehrere Probleme, die sich auf Ihr Layout auswirken.

Zuerst verwenden einige der Widgets innerhalb Appself als das übergeordnete Element, einige verwenden self.parent. Sie sollten alle self in diesem speziellen Fall verwenden. Also, das erste, was zu tun ist, ändern Sie die Elternoption von Treeview zu self.

self.tree = ttk.Treeview(self) 

Zweitens, da Ihr Hauptcode app.pack() anrufen, sollten Sie nicht self.grid fordern werden. Entfernen Sie die Zeile `self.grid (row = 0, column = 0, sticky =" nsew "). Es ist überflüssig.

Drittens verwenden Sie sehr ungewöhnlichen Code, um die Menüleiste hinzuzufügen. Sie müssen das Menü des Hauptfensters konfigurieren. Es gibt keine Notwendigkeit, dies in einen try/except Block zu setzen, und es gibt keinen Grund, self.tk.call zu verwenden. Einfach dies tun:

self.parent.configure(menu=self.menubar) 

Dies setzt voraus, dass self.parent in der Tat das Fenster Wurzel ist. Wenn Sie nicht diese Annahme zwingen wollen, können Sie winfo_toplevel() verwenden, das ist immer das oberste Fenster zurück:

self.parent.winfo_toplevel().configure(menu=self.menubar) 

Schließlich, da Sie verwenden grid, müssen Sie mindestens eine Zeile und eine Spalte geben ein "Gewicht", so dass tkinter weiß, wie man zusätzlichen Platz reserviert (z. B. wenn der Benutzer die Größe eines Fensters ändert).

In Ihrem Fall sollten Sie das gesamte Gewicht 0 (Null) zu Zeile und Spalte geben, denn das ist, wo Sie das Widget platziert haben, die den meisten Platz braucht:

def __init__(self, parent): 
    ... 
    self.grid_rowconfigure(0, weight=1) 
    self.grid_columnconfigure(0, weight=1) 

Hinweis: Sie‘ Ich möchte auch sicherstellen, dass wenn Sie app.pack() aufrufen, dass Sie es Parameter geben, die es zusätzlichen Raum auch ausfüllen. Andernfalls füllt der Baum "app", aber "app" würde das Fenster nicht füllen.

app.pack(fill="both", expand=True) 

Hier ist ein voll funktionierendes Beispiel mit all diesen Änderungen. Ich gruppierte, um den Haupt-Layout-Code zusammen da, dass der Code einfacher macht, zu visualisieren und leichter zu pflegen:

import Tkinter, ttk 

class App(Tkinter.Frame): 
    def __init__(self,parent): 
     Tkinter.Frame.__init__(self, parent, relief=Tkinter.SUNKEN, bd=2) 
     self.parent = parent   

     self.menubar = Tkinter.Menu(self) 
     self.parent.winfo_toplevel().configure(menu=self.menubar) 

     self.tree = ttk.Treeview(self) 

     self.yscrollbar = ttk.Scrollbar(self, orient='vertical', command=self.tree.yview) 
     self.tree.configure(yscrollcommand=self.yscrollbar.set) 

     self.tree.grid(row=0, column=0, sticky="nsew") 
     self.yscrollbar.grid(row=0, column=1, sticky='nse') 
     self.yscrollbar.configure(command=self.tree.yview) 

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

if __name__ == "__main__": 
    root = Tkinter.Tk() 
    root.title("MyApp") 
    app = App(root) 
    app.pack(fill="both", expand=True) 
    app.mainloop() 

Ihre Frage erwähnte Gitter, aber in diesem Fall, dass Sie durch die Verwendung pack ein paar Zeilen Code speichern könnten . pack zeichnet sich in solchen Layouts aus, in denen Ihre GUI von oben nach unten und/oder von links nach rechts ausgerichtet ist.

self.yscrollbar.pack(side="right", fill="y") 
self.tree.pack(side="left", fill="both", expand=True) 
+0

Ausgezeichnet: Alles, was Sie tun müssen, ist die letzten fünf Zeilen (die Anrufe an grid, grid_rowconfigure and grid_columnconfigure') mit diesen beiden Linien ersetzen! Ich sehe, dass die Bildlaufleiste die Bodenebene der Menüleiste bis zum oberen Rand der Fensterfläche überquert. Kann das behoben werden? –

+0

@smlq: Das ist nicht, was Sie sehen. Die Menüleiste ist unsichtbar, weil du nichts hineingesteckt hast. Was Sie denken ist die Menüleiste ist eigentlich der Header der Baumansicht. Die Menüleiste erstreckt sich immer über die gesamte Breite des Fensters. –

+0

Hoppla! Mein Fehler! Vielen Dank! Heh heh! Tatsächlich benutze ich nur 'pack()'. Es ist sauberer in diesem speziellen Layout. –

Verwandte Themen