verdammt, ich kapier es einfach nicht
Klar, kannst du. Aber einfacher wird es dadurch m.E. nicht.derkai hat geschrieben:sagt mal, kann ich denn nicht auch grid nehmen ?
Da du - bisher jedenfalls - auch keine Widgets hast, die gleiche Abmessungen bekommen sollen, musst du sehen, dass du durch geeignetes Zusammenfassen von Zellen entsprechende Megazellen bekommst. Ich persönlich finde das wesentlich unpraktischer als die Arbeit mit dem pack-Manager und ggf. einigen verschachtelten Frames. Wenn man denen ordentliche Namen gibt, dann behält man auch bei etwas Verschachtelung gut den Überblick.
...musste auch erst einen Abend und einen Nachmittag
googeln und experimentieren bis ich's so hatte wie es sein soll:
Das Canvas-Scroll-Resizing Pattern
Versuche das mal.
Bei Dir fehlte u.a. ein
...mehr sage ich lieber nicht...
Wichtigste Regel:
Tkinter-Funktionalitaet nie mit eigenem umfangreichen Code testen, sondern nur mit Minimalfunktionen.
yipyip
googeln und experimentieren bis ich's so hatte wie es sein soll:
Das Canvas-Scroll-Resizing Pattern
Code: Alles auswählen
import Tkinter as tk
class Scroller(object):
def __init__(self, root):
self.root = root
self.frame = tk.Frame(self.root)
self.canvas = tk.Canvas(self.frame, width=100, height=100, bg='white')
xscroll = tk.Scrollbar(self.root, orient='horizontal')
self.canvas.config(xscrollcommand=xscroll.set)
xscroll.config(command=self.canvas.xview)
yscroll = tk.Scrollbar(self.root, orient='vertical')
self.canvas.config(yscrollcommand=yscroll.set)
yscroll.config(command=self.canvas.yview)
w = 999
self.canvas.config(scrollregion=(0, 0, w, w))
self.canvas.pack(side=tk.LEFT, expand=1, fill=tk.BOTH)
self.frame.grid(row=0, column=0, sticky=tk.N+tk.S+tk.E+tk.W)
yscroll.grid(row=0, column=1, sticky=tk.N+tk.S)
xscroll.grid(row=1, column=0, sticky=tk.E+tk.W)
self.root.grid_columnconfigure(0, weight=1)
self.root.grid_rowconfigure(0, weight=1)
p0 = (0, 0)
p1 = (w >> 1, w - 1)
p2 = (w - 1, 0)
self.canvas.create_line(p0, p1)
self.canvas.create_line(p1, p2)
if __name__ == '__main__':
root = tk.Tk()
Scroller(root)
root.mainloop()
Bei Dir fehlte u.a. ein
Code: Alles auswählen
fenster1.pack(side=tk.LEFT, ...
Wichtigste Regel:
Tkinter-Funktionalitaet nie mit eigenem umfangreichen Code testen, sondern nur mit Minimalfunktionen.
yipyip
@yip yip
ne ne, nicht zu spät. ich gucke mir alles an
ich glaube aber inzwischen, dass die CANVAS bereits etwas
eingebaut haben, was die Funktion xview vereinfacht.
schönen Dank -
cih schaue es mir gleich mal an.
Ich habe aber gesehen, dass auch Du grid verwendet hast.
Davon raten ja leider alle ab.
Kai
ne ne, nicht zu spät. ich gucke mir alles an
ich glaube aber inzwischen, dass die CANVAS bereits etwas
eingebaut haben, was die Funktion xview vereinfacht.
schönen Dank -
cih schaue es mir gleich mal an.
Ich habe aber gesehen, dass auch Du grid verwendet hast.
Davon raten ja leider alle ab.
Kai
imac
20 Zoll
2,4 ghz
20 Zoll
2,4 ghz
Weil du den pack()-Manager nicht richtig einsetzt ...derkai hat geschrieben:ja, aber warum bekomme ich denn dann keinen Frame mehr RECHTS NEBEN die Spielfläche ?
Guckst du hier:
Code: Alles auswählen
import Tkinter as tk
spiel = tk.Tk()
spiel.geometry("1024x768")
linkeseite = tk.Frame(spiel,bg="tomato",width=100)
linkeseite.pack(side=tk.LEFT,fill=tk.Y)
rechteseite = tk.Frame(spiel,bg="peachpuff",bd=3,relief=tk.SUNKEN)
rechteseite.pack(side=tk.LEFT,fill=tk.BOTH,expand=True)
spflaeche = tk.Canvas(rechteseite,bg="white")
spflaeche.pack(expand=True,fill=tk.BOTH,padx=25,pady=30)
rechtsnebencanvas = tk.Frame(spiel,bg="lightblue",width=100)
rechtsnebencanvas.pack(side=tk.LEFT,fill=tk.Y)
schieber = tk.Scrollbar(rechteseite,orient=tk.HORIZONTAL)
schieber.pack(fill=tk.X)
spiel.mainloop()
ok, aber wenn ich jetzt mal einen Teil aus deinem Code nehme :
dann füllst Du nach oben auf : fill=tk.Y
lasse ich das jetzt weg und begrenze das Spielfeld auch in der Höhe,
dann komme ich mit side=tk.LEFT nicht weiter.
dann hilft nur :anchor=tk.nw
Code: Alles auswählen
import Tkinter as tk
spiel = tk.Tk()
spiel.geometry("1024x768")
linkeseite = tk.Frame(spiel,bg="tomato",width=100)
linkeseite.pack(side=tk.LEFT,fill=tk.Y)
spiel.mainloop()
lasse ich das jetzt weg und begrenze das Spielfeld auch in der Höhe,
dann komme ich mit side=tk.LEFT nicht weiter.
dann hilft nur :anchor=tk.nw
Code: Alles auswählen
import Tkinter as tk
spiel = tk.Tk()
spiel.geometry("1024x768")
linkeseite = tk.Frame(spiel,bg="tomato",width=100,height=100)
linkeseite.pack(side=tk.LEFT)
spiel.mainloop()
imac
20 Zoll
2,4 ghz
20 Zoll
2,4 ghz
kommt jetzt die rechte seite dazu, dann baut der die aber nicht nach rechts, sondern drunter :
auch anchor hilft dann nicht mehr weiter - ist immer noch drunter :
Code: Alles auswählen
import Tkinter as tk
spiel = tk.Tk()
spiel.geometry("1024x768")
linkeseite = tk.Frame(spiel,bg="tomato",width=100,height=100)
linkeseite.pack(anchor=tk.NW)
rechteseite = tk.Frame(spiel,bg="peachpuff",bd=3,relief=tk.SUNKEN)
rechteseite.pack(side=tk.LEFT,fill=tk.BOTH,expand=True)
spiel.mainloop()
auch anchor hilft dann nicht mehr weiter - ist immer noch drunter :
Code: Alles auswählen
rechteseite = tk.Frame(spiel,bg="peachpuff",bd=3,relief=tk.SUNKEN)
rechteseite.pack(anchor=tk.NE,fill=tk.BOTH,expand=True)
imac
20 Zoll
2,4 ghz
20 Zoll
2,4 ghz
Das wird sich hier noch reichlich in die Länge ziehen, wenn du immer Scheibchenweise mit dem herausrückst, was deine GUI sonst noch für Features haben soll ...
Wenn ich etwas aufwändigere GUIs zu gestalten habe, dann nehme ich erstmal Papier und Stift (manchmal sogar Buntstifte und Geodreieck ...) und mache per Hand einen Entwurf. Meistens sieht es zwar am Ende dann doch (gewollt) anders aus, aber es hilft mir ungemein, mit einer Vorlage neben der Tastatur an dem zu bauen, was herauskommen soll.
In deinem Fall könntest du z.B. mit einem Zeichenprogramm mal einen Oberflächenentwurf aufbauen, der so ist, wie du es (am Ende veraussichtlich) gerne hättest - mit allem drum und dran. Und das zeigst du uns dann. Oder du beschreibst den vorgesehenen Endaufbau so präzise, dass man sich ein ausreichend genaues Bild davon machen kann.
Und dann sehen wir weiter ...
Wenn ich etwas aufwändigere GUIs zu gestalten habe, dann nehme ich erstmal Papier und Stift (manchmal sogar Buntstifte und Geodreieck ...) und mache per Hand einen Entwurf. Meistens sieht es zwar am Ende dann doch (gewollt) anders aus, aber es hilft mir ungemein, mit einer Vorlage neben der Tastatur an dem zu bauen, was herauskommen soll.
In deinem Fall könntest du z.B. mit einem Zeichenprogramm mal einen Oberflächenentwurf aufbauen, der so ist, wie du es (am Ende veraussichtlich) gerne hättest - mit allem drum und dran. Und das zeigst du uns dann. Oder du beschreibst den vorgesehenen Endaufbau so präzise, dass man sich ein ausreichend genaues Bild davon machen kann.
Und dann sehen wir weiter ...
das ist jetzt aber nicht ganz fair.
Für mich soll das ein Test sein, ob die bisher programmierten
Zeilen auch in einer GUI funktionieren.
Ziel :
Linke Seite :
- einmal Canvas inkl. Scrollbalken mit vorgegener Spielfeldgröße
oben Luft und unten Luft
- einmal Canvas mittig drunter für eine Miniaturansicht der
gesamten Spielfäche
Rechte Seite - mit Luft rum herum :
- Frame mit drei Schaltflächen
oben, links und rechts.
Damit wird dann der Panzer übers Spielfeld bewegt.
das war es doch schon.
Ich habe das ja auch mit meinem Code gezeigt und gefragt,
warum ich nach Erstellung der Spielfläche links, einem Canvas darunter
DANN keinen Frame mehr auf die rechte Seite bekomme.
Kai
Für mich soll das ein Test sein, ob die bisher programmierten
Zeilen auch in einer GUI funktionieren.
Ziel :
Linke Seite :
- einmal Canvas inkl. Scrollbalken mit vorgegener Spielfeldgröße
oben Luft und unten Luft
- einmal Canvas mittig drunter für eine Miniaturansicht der
gesamten Spielfäche
Rechte Seite - mit Luft rum herum :
- Frame mit drei Schaltflächen
oben, links und rechts.
Damit wird dann der Panzer übers Spielfeld bewegt.
das war es doch schon.
Ich habe das ja auch mit meinem Code gezeigt und gefragt,
warum ich nach Erstellung der Spielfläche links, einem Canvas darunter
DANN keinen Frame mehr auf die rechte Seite bekomme.
Kai
imac
20 Zoll
2,4 ghz
20 Zoll
2,4 ghz
und mit "place" sähe das dann so aus :
Da dann aber gesagt wurde, dies besser mit Pack zu versuchen,
kam die Diskussion dann ins Rollen
Kai
Code: Alles auswählen
import Tkinter as tk
from funktionen import *
#Hauptfenster erzeugen
spiel = tk.Tk()
spiel.geometry("1024x768")
spiel.title("Kai s Battle Game")
spiel.config(bg="grey")
#Frame1 erzeugen
fenster1 = tk.Frame(master=spiel,bg="white",width=500,
height=500,bd=2,relief=tk.SUNKEN)
fenster1.place(x=10,y=20)
#Scrollbar erzeugen
xleiste = tk.Scrollbar(master=fenster1,orient=tk.HORIZONTAL)
yleiste = tk.Scrollbar(master=fenster1,orient=tk.VERTICAL)
xleiste.pack(side=tk.BOTTOM,pady=2,fill=tk.X)
yleiste.pack(side=tk.RIGHT,pady=2,fill=tk.Y)
#Canvas im Hauptfenster
spflaeche = tk.Canvas (master=fenster1,width=495,height=495)
erstelle_hexfeldobjekte (spielreihen, ungerade_spalten)
for x in hexdic.iterkeys() :
spflaeche.create_polygon (hexdic[x][0],fill=hexdic[x][2],outline="black")
spflaeche.pack()
#Verknuepfung Scrollbar
xleiste.config(command=spflaeche.xview)
yleiste.config(command=spflaeche.yview)
#Frame2 erzeugen -> Miniaturansicht
fenster2 = tk.Frame(master=spiel,bg="white",width=200,height=200,
bd=2,relief=tk.SUNKEN)
fenster2.place(x=600,y=80)
#Frame3 erzeugen -> Miniaturansicht
fenster3 = tk.Frame(master=spiel,bg="white",width=200,height=200,
bd=2,relief=tk.SUNKEN)
fenster3.place(x=10,y=550)
spiel.mainloop()
Da dann aber gesagt wurde, dies besser mit Pack zu versuchen,
kam die Diskussion dann ins Rollen
Kai
imac
20 Zoll
2,4 ghz
20 Zoll
2,4 ghz
Wenn ich deine verbale Beschreibung richtig verstehe, dann soll es so aussehen:
Dein letzter Code mit der pack/place-Mischung liefert bei mir aber nicht das, was deine verbale Beschreibung angibt.
Code: Alles auswählen
import Tkinter as tk
spiel = tk.Tk()
spiel.geometry("1024x768")
linkeseite = tk.Frame(spiel)
linkeseite.pack(side=tk.LEFT,fill=tk.BOTH,expand=True)
spielfeld = tk.Canvas(linkeseite,bg="white",bd=2,relief=tk.SUNKEN)
spielfeld.pack(expand=True,fill=tk.BOTH,padx=25,pady=20)
schieber_x = tk.Scrollbar(spielfeld,orient=tk.HORIZONTAL)
schieber_x.pack(side=tk.BOTTOM,fill=tk.X)
schieber_y = tk.Scrollbar(spielfeld,orient=tk.VERTICAL)
schieber_y.pack(side=tk.RIGHT,fill=tk.Y)
vorschau = tk.Canvas(linkeseite,bg="white",bd=2,relief=tk.SUNKEN,width=180,height=120)
vorschau.pack(pady=20)
rechteseite = tk.Frame(spiel,bd=3,relief=tk.GROOVE)
rechteseite.pack(side=tk.RIGHT,anchor=tk.N,padx=20,pady=20)
knopfoben = tk.Button(rechteseite,text="oben")
knopfoben.pack(pady=10)
knopfbereich = tk.Frame(rechteseite)
knopfbereich.pack(padx=20,pady=10)
knopflinks = tk.Button(knopfbereich,text="links")
knopflinks.pack(side=tk.LEFT,padx=10)
knopfrechts = tk.Button(knopfbereich,text="rechts")
knopfrechts.pack(side=tk.LEFT,padx=10)
spiel.mainloop()
ja, die Buttons fehlen !
ich wußte nicht, dass man SIDE und ANCHOR gleichzeitig
benutzen kann. Jetzt wird mir einiges klarer.
Du benutzt immer einen Frame, ohne eine Größe vorzugeben
und packst die Elemente einfach rein, richtig ?
ich habe es mal ergänzt um das Spielfeld + bewegliche Schieber :
Vielen DANK für Deine unendliche Geduld
Kai
ich wußte nicht, dass man SIDE und ANCHOR gleichzeitig
benutzen kann. Jetzt wird mir einiges klarer.
Du benutzt immer einen Frame, ohne eine Größe vorzugeben
und packst die Elemente einfach rein, richtig ?
ich habe es mal ergänzt um das Spielfeld + bewegliche Schieber :
Code: Alles auswählen
import Tkinter as tk
from funktionen import *
spiel = tk.Tk()
spiel.geometry("1024x768")
frame1 = tk.Frame(spiel)
frame1.pack(side=tk.LEFT,fill=tk.BOTH,expand=True)
spielfeld = tk.Canvas(frame1,bg="white",bd=2,relief=tk.SUNKEN)
erstelle_hexfeldobjekte ()
for x in hexdic.iterkeys() :
spielfeld.create_polygon (hexdic[x][0],fill=hexdic[x][2],outline="black")
spielfeld.pack(expand=True,fill=tk.BOTH,padx=25,pady=20)
schieber_x = tk.Scrollbar(spielfeld,orient=tk.HORIZONTAL)
schieber_x.pack(side=tk.BOTTOM,fill=tk.X)
schieber_y = tk.Scrollbar(spielfeld,orient=tk.VERTICAL)
schieber_y.pack(side=tk.RIGHT,fill=tk.Y)
schieber_x.config(command=spielfeld.xview)
schieber_y.config(command=spielfeld.yview)
vorschau = tk.Canvas(frame1,bg="white",bd=2,relief=tk.SUNKEN,width=200,height=200)
vorschau.pack(pady=20)
frame2 = tk.Frame(spiel,bd=3,relief=tk.GROOVE)
frame2.pack(side=tk.RIGHT,anchor=tk.N,padx=20,pady=20)
knopfoben = tk.Button(frame2,text="oben")
knopfoben.pack(pady=10)
knopfbereich = tk.Frame(frame2)
knopfbereich.pack(padx=20,pady=10)
knopflinks = tk.Button(frame2,text="links")
knopflinks.pack(side=tk.LEFT,padx=10)
knopfrechts = tk.Button(frame2,text="rechts")
knopfrechts.pack(side=tk.LEFT,padx=10)
spiel.mainloop()
Kai
imac
20 Zoll
2,4 ghz
20 Zoll
2,4 ghz
"vergrössert" sich quasi der Frame hier um das Widget Vorschau ?
Kai
Code: Alles auswählen
vorschau = tk.Canvas(frame1,bg="white",bd=2,relief=tk.SUNKEN,width=220,height=220)
vorschau.pack(anchor=tk.W,pady=10,padx=25)
imac
20 Zoll
2,4 ghz
20 Zoll
2,4 ghz
Ja, könnte man so sagen.
Ein Frame gibt so viel Platz frei, wie die in ihm platzierten Widgets für die Anzeige benötigen bzw. einfordern. Mittels der Optionen des packers (fill und extend) kann man diesen Platzbedarf eben auch künstlich in die Höhe schrauben.
Und mittels verschachtelter Frames bekommst du letztlich alles hin, ohne dabei auf die Flexibilität des pack()-Managers gegenüber place() verzichten zu müssen.
Ein Frame gibt so viel Platz frei, wie die in ihm platzierten Widgets für die Anzeige benötigen bzw. einfordern. Mittels der Optionen des packers (fill und extend) kann man diesen Platzbedarf eben auch künstlich in die Höhe schrauben.
Und mittels verschachtelter Frames bekommst du letztlich alles hin, ohne dabei auf die Flexibilität des pack()-Managers gegenüber place() verzichten zu müssen.
Sorry, muss mich korrigieren;
So ist es besser:
Canvas-Scroll-Resizing Pattern
Nimmt man pack() fuer die Scrollbars, so stehen
diese aufeinander, was sehr unschoen und 'unprofessionell'
aussieht, daher habe ich grid() genommen, damit diese
sich nur an einer Ecke beruehren.
Wie numerix schon sagte, kann man pack() und grid()
indirekt(!) mixen, indem man diese in verschiedenen Frames benutzt.
yipyip
So ist es besser:
Canvas-Scroll-Resizing Pattern
Code: Alles auswählen
import Tkinter as tk
class Scroller(object):
def __init__(self, root):
self.root = root
self.frame = tk.Frame(self.root)
self.canvas = tk.Canvas(self.frame, width=100, height=100, bg='white')
self.x_scroll = tk.Scrollbar(self.frame, orient='horizontal')
self.canvas.config(xscrollcommand=self.x_scroll.set)
self.x_scroll.config(command=self.canvas.xview)
self.y_scroll = tk.Scrollbar(self.frame, orient='vertical')
self.canvas.config(yscrollcommand=self.y_scroll.set)
self.y_scroll.config(command=self.canvas.yview)
w = 999
self.canvas.config(scrollregion=(0, 0, w, w))
self.canvas.grid(row=0, column=0, sticky=tk.N+tk.S+tk.W+tk.E)
self.frame.pack(fill=tk.BOTH, expand=1)
self.y_scroll.grid(row=0, column=1, sticky=tk.N+tk.S)
self.x_scroll.grid(row=1, column=0, sticky=tk.E+tk.W)
# enable canvas resizing
self.frame.grid_columnconfigure(0, weight=1)
self.frame.grid_rowconfigure(0, weight=1)
p0 = (0, 0)
p1 = (w >> 1, w - 1)
p2 = (w - 1, 0)
self.canvas.create_line(p0, p1, p2)
if __name__ == '__main__':
root = tk.Tk()
Scroller(root)
root.mainloop()
diese aufeinander, was sehr unschoen und 'unprofessionell'
aussieht, daher habe ich grid() genommen, damit diese
sich nur an einer Ecke beruehren.
Wie numerix schon sagte, kann man pack() und grid()
indirekt(!) mixen, indem man diese in verschiedenen Frames benutzt.
yipyip
ich habe den Code von Numerix jetzt von links nach rechts, vor und zurück probiert. Ich muss sagen, ich resigniere gerade.
Was ich dabei nicht kapiere.
1. ich erstelle ein Hauptfenster mit :
2. Da es ein Canvas und zwei Scrollbalken unter einem Hut
geben soll, wird danach ein Frame erstellt :
UND ich verstehe einfach nicht, warum es SOOOO komliziert ist,
diesen Frame in die linke obere Ecke zu platzieren ?
Geht das nicht einfacher ?
Warum kann man dieses nur links, rechts, oben und unten ?
Oder ist das nicht so ?
Wann benutze ich SIDE und wann benutze ich ANCHOR ?
Bisher war Python für mich schierig, aber immer wieder nach genügend nachdenken auch wieder logisch.
Hier hört meine Logik aber auf ?
Und daher noch einmal meine Frage -
Warum nicht place ?
Das wäre um ein vielfaches einfacher, wenn man eine Spielfläche Stück für Stück erweitern möchte.
... duck und weg
Kai
Was ich dabei nicht kapiere.
1. ich erstelle ein Hauptfenster mit :
Code: Alles auswählen
spiel = tk.Tk()
spiel.geometry("1024x768")
geben soll, wird danach ein Frame erstellt :
Code: Alles auswählen
frame1 = tk.Frame(spiel)
frame1.pack(side=tk.LEFT,fill=tk.BOTH,expand=True)
diesen Frame in die linke obere Ecke zu platzieren ?
Geht das nicht einfacher ?
Warum kann man dieses nur links, rechts, oben und unten ?
Oder ist das nicht so ?
Wann benutze ich SIDE und wann benutze ich ANCHOR ?
Bisher war Python für mich schierig, aber immer wieder nach genügend nachdenken auch wieder logisch.
Hier hört meine Logik aber auf ?
Und daher noch einmal meine Frage -
Warum nicht place ?
Das wäre um ein vielfaches einfacher, wenn man eine Spielfläche Stück für Stück erweitern möchte.
... duck und weg
Kai
imac
20 Zoll
2,4 ghz
20 Zoll
2,4 ghz
Du gehst einfach falsch an die Sache heran. Du fängst mit einem grossen leeren Container mit einer festen Grösse an und willst da etwas oben links platzieren. Das geht so nicht.
Hör auf dem Fenster eine feste Grösse zu geben und platziere Deinen Frame da drin. Wenn Du dann rechts und unten weitere Elemente unterbringst, dann ist der Frame *automatisch* oben links.
Mit `pack()` kann man Widgets von links nach rechts, rechts nach links, oben nach unten, oder unten nach oben in einem Container anordnen. Da man auch Container wieder in Containern anordnen kann, ist letztendlich jede Richtung/Kombination möglich.
`side` benutzt man um zu sagen an welcher Seite im Container das Widget hinzu gefügt werden soll. `anchor` bestimmt, wo im zur Verfügung stehenden Platz das Widget verankert werden soll.
Du musst bei `pack()` und `grid()` gedanklich nicht von einem grossen Fenster ausgehen wo Sachen platziert werden, sondern von den einzelnen Widgets die zu grösseren zusammen gesetzt werden. Widgets haben in der Regel eine minimale Grösse und die Container legen sich da so eng wie möglich drum herum. Wenn ein Widget in einem Container von freier Fläche umgeben ist, weil andere Widgets im gleichen Container höher oder breiter sind, kann man mit `anchor` festlegen wo das Widget innerhalb der Freifläche "hin rutschen" soll. Wenn man nichts angibt, dann wird es mittig platziert. Oder man gibt mit `fill` an, dass das Widget nicht mit seiner mimimalen Grösse angezeigt werden soll, sondern vorhandenen Platz ausfüllen soll.
`place()` ist Mist, weil Du damit keine GUIs hinbekommst die überall korrekt angezeigt werden und Änderungen sehr kompliziert werden.
Hör auf dem Fenster eine feste Grösse zu geben und platziere Deinen Frame da drin. Wenn Du dann rechts und unten weitere Elemente unterbringst, dann ist der Frame *automatisch* oben links.
Mit `pack()` kann man Widgets von links nach rechts, rechts nach links, oben nach unten, oder unten nach oben in einem Container anordnen. Da man auch Container wieder in Containern anordnen kann, ist letztendlich jede Richtung/Kombination möglich.
`side` benutzt man um zu sagen an welcher Seite im Container das Widget hinzu gefügt werden soll. `anchor` bestimmt, wo im zur Verfügung stehenden Platz das Widget verankert werden soll.
Du musst bei `pack()` und `grid()` gedanklich nicht von einem grossen Fenster ausgehen wo Sachen platziert werden, sondern von den einzelnen Widgets die zu grösseren zusammen gesetzt werden. Widgets haben in der Regel eine minimale Grösse und die Container legen sich da so eng wie möglich drum herum. Wenn ein Widget in einem Container von freier Fläche umgeben ist, weil andere Widgets im gleichen Container höher oder breiter sind, kann man mit `anchor` festlegen wo das Widget innerhalb der Freifläche "hin rutschen" soll. Wenn man nichts angibt, dann wird es mittig platziert. Oder man gibt mit `fill` an, dass das Widget nicht mit seiner mimimalen Grösse angezeigt werden soll, sondern vorhandenen Platz ausfüllen soll.
`place()` ist Mist, weil Du damit keine GUIs hinbekommst die überall korrekt angezeigt werden und Änderungen sehr kompliziert werden.
Hallo derkai
Wer mit Tkinter eine GUI erstellt wird nicht um dessen Layout-Möglichkeiten herumkommen. Dabei ist das Wort 'Frustration' und 'Resignation' keine Seltenheit. Wenn einer behauptet er sei noch nie mit den beiden Zuständen konfrontiert worden lügt aus meiner Sicht. Gewisse Layouteigenschaften können sich auf den verschiedenen OS-Platformen und Tk-Versionen auch wieder unterschiedlich verhalten.
place() (präziser Plattenleger)
grid() (Gefängniswärter)
place() Künstler und Zauberer
Da muss sich schlussendlich jeder selbe entscheiden welchen Layoutmanager er einsetzen will.
Der Pack-Layoutmanager ist sicher keine schlechte Variante. Hier kannst du mit einer Unzahl von Frames fast alles hinkriegen. Ich würde aber die GUI wie hier schon einige Male erwähnt wurde planen. Es muss nicht unbedingt mit Bleistift, Papier und Radiergummi sein du kannst auch mit einem Zeichen-Programm z.B. 'Draw', welches zum OpenOffice gehört verwenden.
Meistens ist die Planung eine Top-Down Angelegenheit. Zuerst die äusseren Frames, dann die inneren. Auch im Skript sollten der Code für die die einzelnen Frames nicht Zeile an Zeile geschrieben werden. Zwischenräume sind und Dokumentation sind nicht verboten. Wird dies vernachlässigt, verliert einer schnell einmal die Übersicht.
Bei den Platzierungs-Optionen 'side' und 'anchor' würde ich einemal versuchen nur die 'side'-Option zu gebrauchen.
Hier ein Beispiel wie du eines deine Frames in der oberen linken Ecke platzierst:
Was möchtest du als nächstes?
Gruss wuf
Wer mit Tkinter eine GUI erstellt wird nicht um dessen Layout-Möglichkeiten herumkommen. Dabei ist das Wort 'Frustration' und 'Resignation' keine Seltenheit. Wenn einer behauptet er sei noch nie mit den beiden Zuständen konfrontiert worden lügt aus meiner Sicht. Gewisse Layouteigenschaften können sich auf den verschiedenen OS-Platformen und Tk-Versionen auch wieder unterschiedlich verhalten.
place() (präziser Plattenleger)
grid() (Gefängniswärter)
place() Künstler und Zauberer
Da muss sich schlussendlich jeder selbe entscheiden welchen Layoutmanager er einsetzen will.
Der Pack-Layoutmanager ist sicher keine schlechte Variante. Hier kannst du mit einer Unzahl von Frames fast alles hinkriegen. Ich würde aber die GUI wie hier schon einige Male erwähnt wurde planen. Es muss nicht unbedingt mit Bleistift, Papier und Radiergummi sein du kannst auch mit einem Zeichen-Programm z.B. 'Draw', welches zum OpenOffice gehört verwenden.
Meistens ist die Planung eine Top-Down Angelegenheit. Zuerst die äusseren Frames, dann die inneren. Auch im Skript sollten der Code für die die einzelnen Frames nicht Zeile an Zeile geschrieben werden. Zwischenräume sind und Dokumentation sind nicht verboten. Wird dies vernachlässigt, verliert einer schnell einmal die Übersicht.
Bei den Platzierungs-Optionen 'side' und 'anchor' würde ich einemal versuchen nur die 'side'-Option zu gebrauchen.
Hier ein Beispiel wie du eines deine Frames in der oberen linken Ecke platzierst:
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# Skriptname: frame_test_01.py
import Tkinter as tk
if __name__ == '__main__':
root = tk.Tk()
#~~ Behälter in welchem mein Frame links oben platziert werden soll.
# Dieser Behälter wird an die linke Seite des noch nicht skalierten
# Hauptfenster 'root' geklebt.
container_frame_left = tk.Frame(root)
container_frame_left.pack(side='left', fill='y')
#~~ Mein Frame das ich links oben platzieren möchte
# Das Frame wird an die obere Kante des Behälters 'container_frame_left'
# geklebt.
my_left_top_frame = tk.Frame(container_frame_left, bg="steelblue3",
width=200, height=200)
my_left_top_frame.pack(side='top')
#~~ Das Hauptfenster 'root' wird auf die gewünschte Grösse gebracht
root.geometry("1024x764")
root.mainloop()
Gruss wuf
Take it easy Mates!