Tkinter: grid oder pack in einem raster?
Baue ich noch eine GUI für eine software und wollen, um dies zu erreichen:
######################################
# | some title #
# menu upper |----------------------#
# | #
# | CANVAS #
# menu lower | #
# | #
#------------------------------------#
# statusbar #
######################################
Menü oben hat einige high-level-Funktionalität, Menü niedrigeren verändert sich in Abhängigkeit von Benutzereingaben. Statusbar ändert seinen Inhalt oft.
Leider Tkinter weigert zu arbeiten.
Mithilfe der grid-layout-manager ich nicht in der Lage waren zu schaffen, eine stabile Konstruktion und das hinzufügen von Inhalten, wie Beschriftungen und Tasten, um das Menü auf der linken Seite:
self.root = tk.Tk()
self.root.resizable(width=0, height=0)
self.root.title("some application")
# menu left
self.menu_left = tk.Frame(self.root, width=150, bg="#ababab")
self.menu_left.grid(row=0, column=0, rowspan=2, sticky="ns")
self.menu_left_upper = tk.Frame(self.menu_left, width=150, height=150, bg="red")
self.menu_left_upper.grid(row=0, column=0)
# this label breaks the design
#self.test = tk.Label(self.menu_left_upper, text="test")
#self.test.pack()
self.menu_left_lower = tk.Frame(self.menu_left, width=150, bg="blue")
self.menu_left_lower.grid(row=1, column=0)
# right area
self.some_title_frame = tk.Frame(self.root, bg="#dfdfdf")
self.some_title_frame.grid(row=0, column=1, sticky="we")
self.some_title = tk.Label(self.some_title_frame, text="some title", bg="#dfdfdf")
self.some_title.pack()
self.canvas_area = tk.Canvas(self.root, width=500, height=400, background="#ffffff")
self.canvas_area.grid(row=1, column=1)
self.root.mainloop()
Diesem design funktionierte ohne Inhalt im Menü auf der linken Seite. Immer wenn ich etwas in self.menu_left_upper
oder self.menu_left_lower
, wie die test
label, mein design kaputt: die Menü-frames verschwunden.
Darüber hinaus auch mit columnspan, ich hatte zu entfernen die statusbar, weil, wenn es Hinzugefügt wurde, werden die Menüs auf der linken Seite verschwand, wieder.
Mit pack-layout-manager ich habe diese:
######################################
# | some title #
# |----------------------#
# menu upper | #
# | CANVAS #
# | #
# menu lower | #
# |----------------------#
# | statusbar #
######################################
Da wollte ich den Menü-frame auf der linken Seite zu verbrauchen, den vollen y-Raum, den ich gemacht es wachsen mit pack(side="left", expand=True, fill="both")
, aber das setup immer verneint die statusbar zu gehen, für die volle Breite.
Neben der reinen pack-manager-code sieht "hässlich". Ich denke, dass ein design mit einem grid-manager ist "klarer". Daher dachte ich ein raster-oder ein pack-layout in einem raster-layout wäre schön?
Kann jemand helfen? Ich bin stecken in der GUI-Hölle :/
- Bitten Sie um Hilfe mit Gitter, oder für Hilfe bei der Verwendung von pack, oder haben Sie nicht Sorge, was ist, so lange gibt es das gewünschte Aussehen? Wie funktioniert
pack
code hässlich Aussehen? Es ist nur code. - Ich nicht, egal, was verwendet wird, solange es funktioniert. Allerdings würde ich lieber den grid-manager, da ein grid-layout macht mehr Sinn für mich. Es ist leicht zu verstehen und zu erweitern, während mit viel
pack()
's mit verschiedenenside=...
Attribute sieht irgendwie verwirrend für mich. - Wollen Sie "Menü oben" und "Menü unten" auf jeden Anteil 50% der Fläche?
- Vorzugsweise ja. Ich habe versucht, zu spielen mit der
weight=...
Attribut, aber meine versuche, dies hat nicht funktioniert, auch.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dem Schlüssel zu tun, das layout ist methodisch, und verwenden Sie das richtige Werkzeug
für den job ist. Es bedeutet auch, dass man manchmal brauchen, um kreativ zu sein.
Das bedeutet, dass mit
grid
bei der Verlegung von Dingen in einergrid
, und mitpack
bei der Verlegung Dinge aus top-to-bottom odervon Links nach rechts.
Den anderen Schlüssel ist, um Ihre layout-code zusammen. Es ist viel, viel
leichter zu visualisieren und ändern Sie das layout, wenn alles in einem block
code.
In Ihrem Fall scheinen Sie drei oder vier verschiedene Bereiche, je nach
wie man zählt. Wenn Sie verwenden möchten
grid
es wird am einfachsten seinkombinieren Sie "Menü oben" und "Menü unten" in einen Rahmen, und zu behandeln, dass
ganze Bild als eine Zelle der Tabelle. Es sieht aus wie Sie bereits tut, die,
das ist gut so.
Also, lasst uns beginnen mit diesen Haupt-Bereichen:
Jedes mal, wenn Sie
grid
sind, müssen Sie mindestens eine Zeile und eineSpalte ein positives Gewicht, so dass tkinter weiß, wo Sie zu verwenden
'nicht zugeordneten' Speicherplatz. In der Regel gibt es ein widget, das ist die "main"
- widget. In diesem Fall ist es die Leinwand. Sie wollen sicherstellen, dass die
Zeile und Spalte für die Leinwand hat ein Gewicht von 1 (eins):
Hinweis: die Verwendung
pack
stattgrid
würde sparen Sie zwei Zeilen code, dapack
nicht notwendig, daß Sie die GEWICHTE der Weggrid
tut.Nächsten, die wir lösen müssen das problem die Menü-Bereiche. Standardmäßig
frames schrumpfen zu passen Ihre Inhalte, die ist, warum das hinzufügen der label
brach Ihr layout. Sie waren gar nicht sagen, tkinter, was zu tun ist mit extra viel Platz, damit die Bilder verkleinert, um zu passen, und zusätzlichen Platz ging ungenutzt.
Da möchte man "menu_upper" und "menu_lower" zu
jede Aktie 50% der Fläche,
pack
ist die einfachste Lösung. Sie könnenverwenden
grid
, aber es erfordert mehr Zeilen code hinzufügen, um die Zeile und Spalte gewichten.Hier ist eine funktionierende version, mit der statusbar. Beachten Sie, wie es sich verhält, genau wie es sein sollte, wenn Sie die Fenstergröße ändern:
Auf einem nicht verwandten note: ich würde Sie ermutigen, zu nicht entfernen Sie die Fähigkeit für den Benutzer, um die Größe der Fenster. Sie wissen besser als Sie, was Ihre Anforderungen sind. Wenn Sie
grid
undpack
richtig, die GUI wird die Größe perfekt.Hinzufügen von den folgenden code direkt vor
self.root.mainloop()
erreicht, was Sie suchenself.test = tk.Label(self.menu_left_upper, text="test")
undself.test.pack()
oderself.test.grid()
Menü oben / unten auf der linken Seite verschwindet.self.test
eine Polsterung (padx
undpady
)?Indem Sie in der Zeile:
Zwischen Ihren
menu_left_upper
Rahmen undmenu_left_upper.mainloop()
Dies funktioniert so:
Siehe link zu einer anderen Frage, wo das kam von
Um Ihren status bar einfach umzusetzen, andere Rahmen-und raster-Methode:
Dann ist dein plan funktioniert.
Hoffe es hilft 🙂
PS. Auch der Grund, warum alle
self
Attribute?BEARBEITEN:
Die Arbeit, die Sie tun müssen:
Mein Ergebnis
.grid_propagate(False)
: die Zuordnung dieser zumenu_left
nur, ummenu_left_upper
nur, ummenu_left_lower
nur oder Kombinationen von diesen. Keiner hat gearbeitet. Das Menü und die sub-frames korrekt angezeigt ohne Inhalt, aber sobald z.B. dietest
- label wird Hinzugefügt, ummenu_left_upper
dem Rahmen verschwindet.menu_left_upper.grid
Methodepack
wennpack
Sinn macht, verwendengrid
wenngrid
Sinn macht. Der einzige Schlüssel ist, können Sie nicht verwenden Sie Sie zusammen für widgets, die einen gemeinsamen Elternteil haben.grid_propagate
ist selten die richtige Antwort, und ist es nicht notwendig, dieses problem zu lösen.