Python Tkinter Frame-Layout, Gewicht und Größenänderung, Grid Geometry Manager

Oct 08 2020

Ich glaube, ich verstehe etwas nicht über die Funktionsweise von Grid ...

Meine Frage scheint mit dieser SO-Frage zu tun zu haben : Python tkinter Text-Widget füllt einen Rahmen mit fester Größe mithilfe eines Rasters

Worauf die Antwort lautete, dass ein Gegenstand gewichtet werden muss, damit er mithilfe der Funktionen grid_columnconfigure()und den zusätzlichen Platz einnimmt grid_rowconfigure().

Unten finden Sie den Code für ein einfaches Beispiel. Was ich versuche zu erreichen ist in der Lage , die Größe des zu spezifizieren frame0, haben sie auf alle Seiten der Root - Fenster geklebt werden, und dann das Kind Rahmen hat, frame1stecken zu frame0links, oben, rechts, und zu strecken / schrumpfen wenn die Größe des Hauptfensters der App geändert wird.

Daher würde ich zunächst erwarten, dass die Anwendung im Grunde genommen mit einer Größe von 500 x 350 gestartet wird. frame1wäre so hoch wie es natürlich ist und im Grunde 500 Pixel breit (minus ein wenig zum Auffüllen).

Nach dem Kommentar von acw1668 habe ich den Code aktualisiert, um ihn zu konfigurieren rootund auf 1 zu setzen. Die Größe des Eintrags variiert nun, um jeden horizontalen Raum einzunehmen, genau wie ich es wollte. Aber die GUI startet immer noch in "natürlicher" Größe, obwohl ich eine explizite Größe angegeben habe frame0. Ich verstehe nicht, warum der Geometriemanager 500x350 nicht als natürliche Größe behandelt und diese zuweist.

Kann jemand sehen, wie der anfängliche Start wie erwartet dimensioniert wird?

#!/usr/bin/env python3

from tkinter import *
from tkinter import ttk

root = Tk()
root.title("Layout Problem")
root.grid_columnconfigure(0, weight=1)
root.grid_rowconfigure(0, weight=1)

frame0 = ttk.Frame(root, padding=4, width=500, height=350)
frame0.grid_columnconfigure(0, weight=1)
frame0.grid_rowconfigure(0, weight=1)
frame0.grid(column=0, row=0, sticky=(W, N, E, S))

frame1 = ttk.Frame(frame0, padding=4)
frame1.grid_columnconfigure(1, weight=1)
frame1['borderwidth'] = 2
frame1['relief'] = "ridge"
frame1.grid(column=0, row=0, sticky=(W, N, E))

# add widgets to 'frame1'
ttk.Label(frame1, text="Label: ").grid(row=0, column=0, sticky=W)

entryValue = StringVar()
ttk.Entry(frame1, textvariable=entryValue)\
    .grid(row=0, column=1, sticky=(W, E))
entryValue.set("Entry")

ttk.Button(frame1, text="Button")\
    .grid(row=0, column=2, sticky=E)

root.mainloop()

Antworten

user1441004 Oct 09 2020 at 00:34

Nachfolgend finden Sie den Code nach Einbeziehung der Vorschläge von acw1668.

Die GUI wird jetzt mit der erwarteten Größe gestartet. Es gibt eine Art sekundäres Problem darin, dass der Rahmen jetzt nicht unter 500 px Breite schrumpft (dh der Eintrag wird nicht auf die natürliche Größe zurückgesetzt), obwohl Sie das Anwendungsfenster zwingen können, kleiner zu werden. Das ist eine Art separates Problem.

Ich kann sehen, dass dieses gesamte Layout und die Größenänderung etwas subtil sind, und ich habe noch einen weiten Weg vor mir. ;)

Hoffentlich hat diese Frage einen pädagogischen Wert für andere, die denselben Weg gehen:

#!/usr/bin/env python3

from tkinter import *
from tkinter import ttk

root = Tk()
root.title("Layout Problem")
root.grid_columnconfigure(0, weight=1, minsize=500)
root.grid_rowconfigure(0, weight=1, minsize=350)

frame0 = ttk.Frame(root, padding=4)
frame0.grid(column=0, row=0, sticky=(W, N, E, S))
frame0.grid_columnconfigure(0, weight=1)
frame0.grid_rowconfigure(0, weight=1)

frame1 = ttk.Frame(frame0, padding=4)
frame1.grid_columnconfigure(1, weight=1)
frame1['borderwidth'] = 2
frame1['relief'] = "ridge"
frame1.grid(column=0, row=0, sticky=(W, N, E))

# add widgets to 'frame1'
ttk.Label(frame1, text="Label: ").grid(row=0, column=0, sticky=W)

entryValue = StringVar()
ttk.Entry(frame1, textvariable=entryValue)\
    .grid(row=0, column=1, sticky=(W, E))
entryValue.set("Entry")

ttk.Button(frame1, text="Button")\
    .grid(row=0, column=2, sticky=E)

root.mainloop()