Tkinter - Anordung der Widgets mit pack, place oder grid

Fragen zu Tkinter.
Antworten
Bettina76
User
Beiträge: 12
Registriert: Dienstag 13. August 2013, 15:42

Hallo,
kann mir bitte hier jmd weiterhelfen:
ich habe folgendens Python-Script:

Code: Alles auswählen

import Tkinter
from Tkinter import *

def auswaehlen():
    print "Auswahl"
def einblenden():
    print "Einblenden"


Auswahl_Liste = ["Frühling", "Sommer", "Herbst", "Winter"]

#Dialogfenster wird erstellt...    
main = Tkinter.Tk()

#... und dort ein Text eingefügt.
text = Tkinter.Label (main, text = "Bitte Jahreszeit auswählen", font = ("Arial", 14), anchor = W, justify = "left")
#...mit einem Dialogtext
text.pack()
#text.place(relx = 0.5, rely = 0.5)

     
#...und eine Listbox...
dialog = Tkinter.Listbox(main, height = 10, width = 40, font = ("Arial", 14))
dialog.pack(side = LEFT)

#...worin alle Elemente der Auswahlliste eingefuegt werden
for element in Auswahl_Liste:
    dialog.insert("end",element)

dialog.selection_set(0) #Voreinstellung: erstes Element ausgewählt

     
Detailext = "Details"

    #...und in einem scrollbarem Textfenster anzeigen
scrollbar = Scrollbar(main)
scrollbar.pack(padx = 0,pady = 0, side=RIGHT, fill=Y)
Detailanzeige = Tkinter.Text(main, fg = "#FF99FF", bd = 5, bg = "#CC0099", font =("Arial", 14), width = 40, height = 10, yscrollcomman = scrollbar.set)
    #Detailanzeige.pack()
Detailanzeige.pack(padx = 0,pady = 0, side = RIGHT)
Detailanzeige.insert(END, Detailext)
scrollbar.config(command = Detailanzeige.yview)


    #Button zum Auswaehlen einfuegen   
b = Tkinter.Button(main, text = "Auswählen", command = auswaehlen, font = ("Arial", 14))   
b.pack(padx = 0,pady = 0, side = RIGHT)
   
    #Checkbox zum Einblenden 
Arbeitsstand = Tkinter.StringVar()  
cb = Tkinter.Checkbutton(main, text = "Einblenden", variable = Arbeitsstand, onvalue = "ein", offvalue = "aus", command = einblenden, font = ("Arial", 14))
cb.pack(padx = 0,pady = 0, side = RIGHT)


main.mainloop()

Jetzt möchte ich gern die Widgets so anordnen, dass der Kasten mit Details rechts neben der Listbox ist. Ist er ja schon. Aber leider dazwischen der Button und die Checkbox. Die würde ich gern unter der Listbox haben.
Und den Text ganz oben, wollt ich eigentlich mit justify nach "links" setzen. Hat aber leider irgendwie nicht funktioniert.
Kann mir hier bitte jemand weiterhelfen.
Vielen Dank!
BlackJack

@Bettina76: Bei `pack()` sollte man innerhalb des selben Containerwidgets immer den selben Wert für das `side`-Argument verwenden. Du möchtest also entweder Deine Elemente in `Frame`\s gruppieren und `pack()`\en und die dann in `main()` mit `pack()` platzieren, oder mit `grid()` arbeiten. Oder mit einer Kombination davon.

Ich persönlich verwende `pack()` mit `Frame`\s und `grid()` nur wenn es nicht anders geht oder der GUI-Teil ganz eindeutig „grid-artig” aufgebaut ist.

Du müsstest Deine GUI in Unterkomponenten aufteilen die eine Hauptrichtung haben, die für `pack()` verwendet wird. Welche das in Deinem Fall ist, wird mir aus Deiner Beschreibung nicht so ganz klar. Soll links die Überschrift über der Listbox über der Reihe mit Checkbox, Label, und Schaltfläche sein, und rechts der Detailtext über die ganze Höhe, dann ist die Hauptrichtung ``side=Tkinter.LEFT``. Soll die Überschrift oben sein, Listbox und Detailtext auf gleicher Höhe und darunter die Reihe mit Checkbox, Label, und Schaltfläche mittig angeordnet, dann ist die Hauptrichtung ``side=Tkinter.TOP``.
Bettina76
User
Beiträge: 12
Registriert: Dienstag 13. August 2013, 15:42

Hallo BlackJack,
vielen Dank für die rasche Antwort.
Überschrift oben sein, Listbox und Detailtext auf gleicher Höhe und darunter die Reihe mit Checkbox, Label, und Schaltfläche mittig angeordnet. Das hätt ich vor - also side=Tkinter.TOP
Gruppieren tue ich dann am besten über Tkinter.Frame oder?
Bettina76
User
Beiträge: 12
Registriert: Dienstag 13. August 2013, 15:42

Hallo BlackJack,
mit Gruppieren hat das schon funktioniert, dass jetzt die Listbox neben der Textbox mit den Details steht. Aber ich bekomme es jetz grad nicht hin, dass der Frame Fr2 unter dem Fr1 staht und nicht nebeneinander. Kannst Du mir hier bitte noch einen Tipp geben. Oder jmd aus dem Forum.
Vielen Dank!
Hier mein geändertes Python-Script:

Code: Alles auswählen

import Tkinter
from Tkinter import *

def auswaehlen():
    print "Auswahl"
def einblenden():
    print "Einblenden"


Auswahl_Liste = ["Frühling", "Sommer", "Herbst", "Winter"]

#Dialogfenster wird erstellt...    
main = Tkinter.Tk()

#... und dort ein Text eingefügt.
text = Tkinter.Label (main, text = "Bitte Jahreszeit auswählen", font = ("Arial", 14), anchor = NW)
#...mit einem Dialogtext
text.pack()
#text.place(relx = 0.5, rely = 0.5)

fr1 = Tkinter.Frame(main, width = 200, height = 100, relief = "sunken", bd =3)
fr1.pack(side="left")

#...und eine Listbox...
dialog = Tkinter.Listbox(fr1, height = 10, width = 40, font = ("Arial", 14))
dialog.pack(padx = 0, pady = 0, side = LEFT)

#...worin alle Elemente der Auswahlliste eingefuegt werden
for element in Auswahl_Liste:
    dialog.insert("end",element)

dialog.selection_set(0) #Voreinstellung: erstes Element ausgewählt

     
Detailext = "Details"

    #...und in einem scrollbarem Textfenster anzeigen
scrollbar = Scrollbar(main)
scrollbar.pack(padx = 0,pady = 0, side=RIGHT, fill=Y)
Detailanzeige = Tkinter.Text(fr1, fg = "#FF99FF", bd = 5, bg = "#CC0099", font =("Arial", 14), width = 40, height = 10, yscrollcomman = scrollbar.set)
    #Detailanzeige.pack()
Detailanzeige.pack(padx = 0,pady = 0, side = RIGHT)
Detailanzeige.insert(END, Detailext)
scrollbar.config(command = Detailanzeige.yview)

# wie kann man diesen Frame unter Fr1 setzen? mit pady geht's nicht
fr2 = Tkinter.Frame(main, width = 200, height = 50, bd =0)
fr2.pack(padx = 0,pady = 200, side="left")

    #Button zum Auswaehlen einfuegen   
b = Tkinter.Button(fr2, text = "Auswählen", command = auswaehlen, font = ("Arial", 14), anchor = SW)   
b.pack(padx = 0,pady = 0, side = RIGHT)
   
    #Checkbox zum Einblenden 
Arbeitsstand = Tkinter.StringVar()  
cb = Tkinter.Checkbutton(fr2, text = "Einblenden", variable = Arbeitsstand, onvalue = "ein", offvalue = "aus", command = einblenden, font = ("Arial", 14))
cb.pack(padx = 0,pady = 0, side = RIGHT)


main.mainloop()

Bettina76
User
Beiträge: 12
Registriert: Dienstag 13. August 2013, 15:42

Geht.
Mit side = Tkinter.TOP und Frames. Eigentlich genauso wie empfohlen. Hab nur vorher nicht richtig gelesen
Vielen Dank!
Antworten