Sie sind hier: Python
Zurück zu: Sprachen
Allgemein:
Vorlesungen
Labore
Sinnvolle Programme
Lineare Regression
GUI-Entwurfsarbeit
Single-Format
Design Pattern-Termine
Observer1
Bsp2
Json-Array
Json-Dialogelemente
Webtechnologien
Der Layout-Manager „pack“ arbeitet ähnlich des GridBagLayouts. Nur werden die Elemente beim Einfügen positioniert.
| Parameter | Werte | Erläuterung |
| after | Widget | Das Element wird nach dem Wigdet-Element gepackt. |
| anchor | "n", "ne", "e", "se", "s", "sw", "w", "nw","center" | Anchor à la GridbagLayout. Damit können Elemente, die nicht "gezoomt" werden, zum Beispiel nach links/oben positioniert werden. |
| before | Widget | Das Element wird vor dem Wigdet-Element gepackt. |
| expand | True / False |
wx bzw. wy à la GridbagLayout. Dieser Wert sollte nur beim Wert fill="y" oder fill="both" gesetzt werden. Label, Entry, Checkbox, Buttons brauch kein expand. |
| fill | "x", "y", "both", "none" | fill-Attribut à la GridbagLayout. Wenn man das Fenster vergrößert, wird das UI-Element mitvergrößert. |
| in | Widget | Das Element wird in das Wigdet-Element gepackt. Meist ein LabelFrame. Diese Eigenschaft wird meistens über den Konstruktor gesetzt. |
| ipadx | int | innerer Rand in Pixel |
| ipady | int | innerer Rand in Pixel |
| padx | int | äußerer Rand in Pixel |
| pady | int | äußerer Rand in Pixel |
| side | "left", "right", "top", "bottom" | Layout à la DockPanel von WPF. |
01:# coding=utf8
02: import tkinter
03:
04: class MyApp(tkinter.Frame):
05:
06: def __init__(self, master=None):
07: tkinter.Frame.__init__(self, master)
08: self.pack()
09: self.setGUI()
10:
11: def setGUI(self):
12: self.nameEntry = tkinter.Entry(self)
13: self.nameEntry.pack()
14:
15: self.inputui = tkinter.StringVar()
16: self.inputui.set("Ihr Name...")
17: self.nameEntry["textvariable"] = self.inputui
18:
19: self.bnOk = tkinter.Button(self)
20: self.bnOk["text"] = "Ok"
21: self.bnOk["command"] = self.quit
22: self.bnOk.pack(side="right")
23:
24: self.bnAction = tkinter.Button(self)
25: self.bnAction["text"] = "Action"
26: self.bnAction["command"] = self.onAction
27: self.bnAction.pack(side="right")
28:
29: def onAction(self):
30: s = self.inputui.get()
31: self.inputui.set( "Text: "+s )
# 1. Aufruf-Möglichkeit
root = tkinter.Tk()
app = MyApp(root)
app.mainloop()
# 2. Aufruf-Möglichkeit
root = tkinter.Tk()
root.title("Mein Fenster")
root.geometry("250x100")
app = MyApp(root)
app.mainloop()
Im Bild Samples1-e.png sieht man, dass das Textfeld nicht komplett im Fenster positioniert ist.
Der Layout-Manager ist mit gelben Hintergrund dargestellt.
Auch eine Vergrößerung des Fensters bewirkt nichts.
Abhilfe:
Der Aufruf des pack-Layouts im Konstruktur wird erweitert.
self.pack(expand=True, fill="both", padx="5", pady="5")
Ergebnis:
Samples1-f.png
Nun müssen natürlich auch die UI-Elemente angepasst werden:
mit
self.nameEntry.pack(fill="x", padx="5", pady="5")
wird das Textfeld komplett im Fenster ausgefüllt.
Ein Vergrößern vergrößert auch das Textfeld!
Bild Samples1-g.png
Damit man es einfacher hat sollte man UI-Elemente mit dem Frame-Element zusammenfügen.
Ein "Frame-Element" ist nichts anderes als ein "JPanel" bzw. ein DockPanel.
1) Im Konstruktur verwendet man immer
self.pack(expand=True, fill="both", padx="5", pady="5")
2) Jede "Zeile" im Fenster fügt man in einem Frane ein
inputframe = tkinter.Frame(
self
) # frame wird eingefügt in self
inputframe.background = "red" #"#FF0000"
inputframe.pack(fill="x", side="top" )
self.label1 = tkinter.Label(i
nputframe
) # label wird eingefügt in frame
self.label1["text"] = "Eingabe"
self.label1.config(foreground = "blue" )
self.label1.config(background = "#FFFF00")
self.label1.pack(side="left")
self.inputui = tkinter.Entry(
inputframe
) # Entry wird eingefügt in frame
self.inputui.pack(fill="x",padx="5",pady="5")
Ergebnis:
Bild Samples1-h.png
Bei Vergrößerung:
Bild Samples1-i.png 3) Jeder "Frame" mit fill="both" sollte erst am Schluss eingefügt werden
Der Sinn liegt im DockPanel-Prinzip von WPF.
Beispiel:
Fügt man eine Zeile mit einer Entry ein.
Fügt man eine Zeile mit einer Listbox ein (fill="both")
Fügt man einen Button ein.
Durch die Listbox hat der Schalter keinen Platz mehr.
Erst ab einer bestimmten Größe ist er wieder sichtbar.
In der oberen Abbildung sieht man die drei Frames:
- rot: Eingabezeile
- grün: Texteditor
- blau: "Schalterleiste"
# coding=utf8
import tkinter
from tkinter import messagebox
class MyApp(tkinter.Frame):
def __init__(self, master=None):
tkinter.Frame.__init__(self, master)
self.pack(expand=True, fill="both") # dialog zoomt
self.setGUI()
def setGUI(self):
# pack ist wie das DockPanel in WPF
# erst muessen die "normalen" UI-Elemente eintgetragen werden
# am Schluss werden die UI-Elemente eingetragen, die fill="both" haben
inputframe = tkinter.Frame(self) # „JPanel“ fuer die Eingabe
inputframe.config(background = "red") #"#FF0000"
inputframe.pack(fill="x", side="top" ) # ohne expand, da fill=“x“
self.label1 = tkinter.Label(inputframe, fg="blue", bg="#FFFF00")
self.label1["text"] = "Eingabe"
self.label1.pack(side="left")
self.inputui = tkinter.Entry(inputframe)
self.inputui.pack(expand=True,fill="x",padx="5",pady="5")
self.var_name = tkinter.StringVar()
self.var_name.set("Ihr Name...")
self.inputui["textvariable"] = self.var_name
buttonframe = tkinter.Frame(self) # „JPanel“ fuer die Eingabe
buttonframe.config(background = "blue") #"#FF0000"
# ohne expand, da fill=“x“
buttonframe.pack(fill="x", side="bottom" )
self.bnEsc = tkinter.Button(buttonframe)
self.bnEsc["text"] = "Beenden"
self.bnEsc["command"] = self.quit
self.bnEsc.pack(padx="5", side="right")
self.bnAction = tkinter.Button(buttonframe)
self.bnAction["text"] = "Action"
self.bnAction["command"] = self.onAction
self.bnAction.pack(side="right")
# nun ein Editor mit fill=both
editorframe = tkinter.Frame(self) # „JPanel“ fuer den Editor
editorframe.config(background = "green") #"#FF0000"
editorframe.pack(expand=True,fill="both", side="top" )
sbx = tkinter.Scrollbar(editorframe, orient="horizontal")
sbx.pack(fill="x", side="bottom")
sby = tkinter.Scrollbar(editorframe)
sby.pack(fill="y", side="right")
self.editor = tkinter.Text(editorframe)
self.editor.config(wrap="none") # wrap="word" word char
self.editor.pack(expand=True, fill="both", padx="5",pady="5")
self.editor["xscrollcommand"] = sbx.set
sbx["command"] = self.editor.xview
self.editor["yscrollcommand"] = sby.set
sby["command"] = self.editor.yview
def onAction(self):
str = self.var_name.get()
messagebox.showinfo( "Hello Python", str)
self.editor.insert("end",str+"\r\n")
root = tkinter.Tk()
root.title("Sample2.py (Editor)")
root.geometry("450x400")
app = MyApp(root)
app.mainloop()
Gehe zu: tkinter Layout grid