Tkinter Tutorial - Layout-Verwaltung
In den vorherigen Abschnitten haben wir verschiedene Tkinter-Widgettypen eingeführt, wie z.B. label, button, Drop-Down-Menü, etc. Inzwischen haben wir auch kurz erwähnt, wie man diese Widgets im Programmfenster anordnet. Dies ist der Schlüsselpunkt, den Sie in diesem Abschnitt lernen werden - Tkinter’s Geometrieverwaltungsmethoden.
Tkinter hat drei Geometrieverwaltungsmethoden, nämlich pack
, grid
und place
. Laßt sie uns nacheinander durchgehen.
Tkinter pack
Layout Methode
Die pack
Methode, wie wörtlich genommen, packt das Widget nach der Erstellung in den Fensterrahmen. Wir finden diese Layout-Methode in der Sektion Tkinter Label, wo auch alle pack
Optionen aufgelistet sind.
Wir werden Ihnen zeigen, wie Sie Widgets mit der pack
Methode (auch deren Optionen) layouten können. Ein paar Beispiele helfen, die richtige Konfiguration zu demonstrieren.
Tkinter pack
Layout - Relative Position
import tkinter as tk
app = tk.Tk()
app.geometry("300x200")
buttonW = tk.Button(app, text="West", width=15)
buttonW.pack(side="left")
buttonE = tk.Button(app, text="East", width=15)
buttonE.pack(side="right")
app.mainloop()
Starten Sie das Programm, Sie erhalten ein Fenster wie dieses,
Wie Sie sehen können, rastet buttonWest
auf der linken Seite des Fensters und buttonEast
auf der rechten Seite des Fensters ein. Sie können versuchen, die Größe des Fensters unten zu skalieren, aber Sie werden feststellen, dass sie immer noch an den Seiten des Fensters hängen bleiben und die relative Position sich nicht ändert.
buttonW.pack(side="left")
side
hat vier Optionen -
top
bottom
left
right
Es platziert das Widget auf der side
des Fensters. Wie im Beispiel gezeigt, ist buttonW
auf der linken Seite des Fensters angeordnet, weil side='left'
, während buttonE
auf der rechten Seite des Fensters liegt, weil side='right'
.
Nun haben wir ein interessantes Szenario, was passiert, wenn zwei Widgets die gleiche side
Eigenschaft haben, wie wird das Layout sein?
Versuchen Sie, es selbst zu beantworten, oder überprüfen Sie es, indem Sie die folgenden Codes ausführen.
import tkinter as tk
app = tk.Tk()
app.geometry("300x200")
buttonW = tk.Button(app, text="West", width=15)
buttonW.pack(side="left")
buttonE1 = tk.Button(app, text="East 1", width=15)
buttonE1.pack(side="right")
buttonE2 = tk.Button(app, text="East 2", width=15)
buttonE2.pack(side="right")
app.mainloop()
Tkinter pack
, um Widgets intern und extern zu polstern
In einigen Fällen müssen Sie innerhalb oder außerhalb des Widgets etwas Füllung hinzufügen, damit es weniger Stau zwischen den Widgets und auch zwischen dem Widget-Text und den Widget-Grenzen gibt. Jetzt brauchen Sie Optionen wie padx
, pady
, ipadx
und ipadx
.
import tkinter as tk
app = tk.Tk()
app.geometry("300x200")
buttonW = tk.Button(app, text="West")
buttonW.pack(side="left", ipadx=20, padx=30)
buttonE = tk.Button(app, text="East")
buttonE.pack(side="right", ipadx=20, padx=30)
app.mainloop()
Beide Buttons fügen innere 20 Einheiten Padding und äußere 30 Einheiten im x
hinzu, und die Einheit ist Pixel, aber nicht die Breite eines Zeichens.
Tkinter pack
Layout Füllung in x, y Richtung
Die folgende Code-Implementierung könnte die Widget-Dimension automatisch auf die gleiche Breite oder Höhe wie das Fenster füllen, und wenn Sie das Fenster zoomen, kann sich die Größe des Controls automatisch mit der Größe des Fensters ändern.
import tkinter as tk
app = tk.Tk()
app.geometry("300x200")
buttonX = tk.Button(app, text="Fill X", bg="red", height=5)
buttonX.pack(fill="x")
buttonY = tk.Button(app, text="Fill Y", bg="green", width=10)
buttonY.pack(side="left", fill="y")
app.mainloop()
butonX.pack(fill='x')
bedeutet, dass buttonX
die Breite des gesamten Fensters ausfüllt. Ähnlich wird fill='y'
die Höhe des ganzen Fensters füllen, und währenddessen wird fill='both'
sowohl die Breite als auch die Höhe füllen.
Tkinter pack
Layout Option expand
- automatisch erweitern
Die Option fill=
oberhalb von fill=
füllt das Widget automatisch in x
und/oder y
Richtung, wenn die Fenstergröße verändert wird. Eine weitere ähnliche Anforderung ist, wie man automatisch den gesamten Inhalt anzeigt, wenn das Widget mehrere Optionen enthält, wie z.B. eine Liste?
import tkinter as tk
import calendar
app = tk.Tk()
buttonX = tk.Button(app, text="Label ", bg="blue", height=5)
buttonX.pack(fill="x")
listboxA = tk.Listbox(app, width=10)
listboxA.pack(fill="both", expand=1)
for i in range(1, 13):
listboxA.insert(tk.END, calendar.month_name[i])
app.mainloop()
Wenn expand=True
oder expand=1
, listet die Listbox alle Einträge auf, von January
bis December
, wie im obigen Beispiel gezeigt.
Wenn expand
auf False
gesetzt ist, dann zeigt die Listbox standardmäßig nur die ersten 10 Einträge an. Sie müssen die Maus oder die Richtungstasten benutzen, um die versteckten Einträge anzuzeigen, nachdem die Listbox ausgewählt wurde.
listboxA.pack(fill="both", expand=0)
expand=0
deaktiviert die Listbox, um automatisch alle Einträge anzuzeigen.
Tkinter grid
Layout Methode
Tkinter grid
ist eine weitere und auch die wichtigste Methode der Layout-Geometrie. Dies ist diejenige, die Sie lernen sollten, wenn Sie nur eine einzige Methode unter allen Geometriemanagern lernen wollen.
grid
wird oft in Dialogfeldern verwendet, und Sie könnten die Widgets auf der Basis der Positionskoordinaten des Gitters platzieren. Die grid
Layout-Methode könnte stabile relative Positionen aller Widgets haben.
Das folgende Beispiel wird ein relativ kompliziertes GUI im Vergleich zu den obigen Beispielen erstellen, das so viele Optionen des grid
wie möglich verwendet, die in den nächsten Abschnitten erklärt werden.
import tkinter as tk
app = tk.Tk()
labelWidth = tk.Label(app, text="Width Ratio")
labelWidth.grid(column=0, row=0, ipadx=5, pady=5, sticky=tk.W + tk.N)
labelHeight = tk.Label(app, text="Height Ratio")
labelHeight.grid(column=0, row=1, ipadx=5, pady=5, sticky=tk.W + tk.S)
entryWidth = tk.Entry(app, width=20)
entryHeight = tk.Entry(app, width=20)
entryWidth.grid(column=1, row=0, padx=10, pady=5, sticky=tk.N)
entryHeight.grid(column=1, row=1, padx=10, pady=5, sticky=tk.S)
resultButton = tk.Button(app, text="Get Result")
resultButton.grid(column=0, row=2, pady=10, sticky=tk.W)
logo = tk.PhotoImage(file="python.gif")
labelLogo = tk.Label(app, image=logo)
labelLogo.grid(
row=0,
column=2,
columnspan=2,
rowspan=2,
sticky=tk.W + tk.E + tk.N + tk.S,
padx=5,
pady=5,
)
app.mainloop()
Tkinter grid
column
und row
Optionen
labelWidth.grid(column=0, row=0, ipadx=5, pady=5, sticky=tk.W + tk.N)
Jedes Widget soll in der absoluten Zelle in der grid
-Layoutmethode platziert werden. Die Zellkoordinate wird durch column
und row
bestimmt.
Das labelWidth
Widget wird in der Zelle der Position (0, 0)
platziert. Die Koordinate beginnt in der linken oberen Ecke des Fensters.
Die Optionen ipadx
, ipady
, padx
und pady
sind die gleichen wie bei der pack
Methode.
Tkinter grid
sticky
Option
sticky
bestimmt, wie das Widget an der Zelle haftet, wenn das Widget kleiner als die Zelle ist.
klebrig |
Bedeutung |
---|---|
W |
sich links halten |
E |
sich rechts halten |
N |
obenauf bleiben |
S |
unten ankleben |
Die Standard-Option sticky
ist die Mitte, also W+E+N+S
.
Tkinter columnspan
und rowspan
Optionen
labelLogo.grid(
row=0,
column=2,
columnspan=2,
rowspan=2,
sticky=tk.W + tk.E + tk.N + tk.S,
padx=5,
pady=5,
)
Die Zellkoordinate von labelLogo
ist (columnspan=2, rowspan=0)
und die Größe des Logos ist relativ groß, daher wird ihm eine Zellgröße von 2x2
zugewiesen. columnspan=2
und rowspan=2
bedeutet, dass das Widget eine Spannweite von zwei Zellen sowohl in X
als auch in Y
-Richtung hat, ausgehend von der Position des Widgets.
Tkinter place
Methode
Tkinter place
Methode platziert das Widget an einer absoluten oder relativen Position im Fenster. Wir verwenden immer noch den gleichen Ansatz wie oben, um die Optionen dieser Layout-Methode vorzustellen.
import tkinter as tk
app = tk.Tk()
app.geometry("300x300")
labelA = tk.Label(app, text="Label (0, 0)", fg="blue", bg="#FF0")
labelB = tk.Label(app, text="Label (20, 20)", fg="green", bg="#300")
labelC = tk.Label(app, text="Label (40, 50)", fg="black", bg="#f03")
labelD = tk.Label(app, text="Label (0.5, 0.5)", fg="orange", bg="#0ff")
labelA.place(x=0, y=0)
labelB.place(x=20, y=20)
labelC.place(x=40, y=50)
labelD.place(relx=0.5, rely=0.5)
app.mainloop()
Tkinter place
Absolute Position
labelA.place(x=0, y=0)
labelB.place(x=20, y=20)
Die Optionen x=
und y=
in place
bestimmen die absoluten Positionen des Widgets, die die Einheit als Pixel haben. Zum Beispiel bedeutet labelB.place(x=20, y=20)
, dass labelB
in der Koordinate von (20, 20)
platziert wird.
Tkinter place
Relative Position
Der Nachteil der absoluten Position ist, dass, wenn es andere Widgets im Fenster gibt, die mit relativen Positionen platziert sind, wenn das Fenster gezoomt wird, das Widget, das das Layout der absoluten Position verwendet, möglicherweise die Überlappung mit anderen Widgets hat.
Die place
-Layout-Methode hat auch die Option der relativen Position, das heißt,
labelD.place(relx=0.5, rely=0.5)
Wobei relx
und rely
im Bereich von 0.0~1.0
liegen. Es ist der relative Prozentsatz der Widgetposition zur Fenstergröße.
Zum Beispiel, relx=0.5, rely=0.5
bedeutet, dass das Widget in den 50% der Fensterbreite und 50% der Fensterhöhe platziert wird.
relx=1.0
ist die rechte Begrenzung des Fensters, und rely=1.0
ist die untere Begrenzung des Fensters.
Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.
LinkedIn Facebook