Python Tkinter Frame layout, peso e ridimensionamento, gestore della geometria della griglia

Oct 08 2020

Immagino di non capire qualcosa sul modo in cui funziona Grid ...

La mia domanda sembra correlata a questa domanda SO: Python tkinter Text widget riempie una cornice di dimensioni fisse usando la griglia

La risposta è stata che bisognava dare peso a un articolo per fargli occupare lo spazio extra, utilizzando le funzioni grid_columnconfigure()e grid_rowconfigure().

Di seguito è riportato il codice per un semplice esempio. Quello che sto cercando di ottenere è essere in grado di specificare la dimensione di frame0, farlo attaccare a tutti i lati della finestra principale, quindi avere il frame figlio, frame1essere bloccato a frame0sinistra, in alto, a destra e allungare / restringere quando la finestra principale dell'app viene ridimensionata.

Quindi, inizialmente, mi aspetto che l'applicazione venga avviata fondamentalmente a dimensioni 500x350. frame1sarebbe alto come è naturalmente e fondamentalmente largo 500 pixel (meno un po 'per il riempimento).

Dopo il commento di acw1668, ho aggiornato il codice per configurarlo roote impostarne il peso su 1. La dimensione di Entry ora varia per occupare qualsiasi spazio orizzontale, proprio come volevo. Ma la GUI si avvia ancora a dimensioni "naturali", sebbene io abbia dato una dimensione esplicita a frame0. Non capisco perché il gestore della geometria non tratti 500x350 come dimensione naturale e lo assegni?

Qualcuno può vedere come ottenere le dimensioni del lancio iniziale come previsto?

#!/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()

Risposte

user1441004 Oct 09 2020 at 00:34

Per riferimento, di seguito è riportato il codice dopo aver incorporato i suggerimenti di acw1668.

La GUI ora viene avviata con le dimensioni previste. C'è una sorta di problema secondario in quanto ora il frame non si riduce al di sotto di 500 px di larghezza (cioè, la voce non si comprimerà di nuovo alle dimensioni naturali) sebbene sia possibile forzare la finestra dell'applicazione a essere più piccola. Questa è una specie di problema a parte.

Vedo che c'è un po 'di sottigliezza nell'intero layout e nel ridimensionamento dell'attività e ho ancora molta strada da fare. ;)

Si spera che questa domanda abbia un valore pedagogico per altri che seguono lo stesso percorso:

#!/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()