Tkinter Tutorial - Gestione del layout

  1. Metodo di impaginazione di Tkinter pack
  2. Metodo di impaginazione grid di Tkinter
  3. Metodo place di Tkinter

Nelle sezioni precedenti abbiamo introdotto diversi tipi di widget di Tkinter, come label, button, menu a tendina, ecc. Nel frattempo, abbiamo anche accennato brevemente a come impaginare questi widget nella finestra del programma. Questo è il punto chiave che imparerete in questa sezione - i metodi di gestione della geometria di Tkinter.

Tkinter ha tre metodi di gestione della geometria, cioè, pack, grid, e place. Esaminiamoli uno per uno.

Metodo di impaginazione di Tkinter pack

Il metodo pack, come letteralmente indicato, impacchetta il widget nella cornice della finestra dopo che è stato creato. Ci imbattiamo in questo metodo di impaginazione nella sezione Tkinter Label dove sono elencate anche tutte le opzioni pack.

Vi mostreremo come impaginare i widget con il metodo pack (anche le sue opzioni). Alcuni esempi aiutano a dimostrare la giusta configurazione.

Tkinter pack Layout - Posizione relativa

Tkinter Geometry_Pack_Relative Position.py
import tkinter as tk    
    
app = tk.Tk()
app.geometry('300x200')

buttonW = tk.Button(app, text="West", width=15)
buttonW.pack(side='left')

buttonE = tk.Button(app, text="East", width=15)
buttonE.pack(side='right')

app.mainloop()

Eseguite il programma, otterrete una finestra come questa,

Tkinter pack metodo di disposizione del pacco Tkinter - posizione relativa sul lato del metodo

Come potete vedere, il bottoneWest scatta sul lato sinistro della finestra e il bottoneEast scatta sul lato destro della finestra. Potete provare a scalare le dimensioni della finestra sottostante, ma vi accorgerete che si aggrapperanno ancora ai lati della finestra e la posizione relativa non cambierà.

buttonW.pack(side='left')

Il side ha quattro opzioni -

  1. top
  2. bottom
  3. left
  4. right

Posiziona il widget sul side della finestra. Come illustrato nell’esempio, buttonW è allocato sul lato sinistro della finestra, perché side='left', mentre buttonE è sul lato destro della finestra, perché side='right'.

Ora abbiamo uno scenario interessante, cosa succede se due widget hanno la stessa proprietà side, come sarà il layout?

Provate a rispondere voi stessi, o a controllare eseguendo i seguenti codici.

Tkinter Geometry_Pack_Relative Position Two side.py
import tkinter as tk
    
    
app = tk.Tk()
app.geometry('300x200')

buttonW = tk.Button(app, text="West", width=15)
buttonW.pack(side='left')

buttonE1 = tk.Button(app, text="East 1", width=15)
buttonE1.pack(side='right')

buttonE2 = tk.Button(app, text="East 2", width=15)
buttonE2.pack(side='right')

app.mainloop()

Tkinter pack per aggiungere il padding interno ed esterno del widget

In alcuni casi, è necessario aggiungere un po’ di imbottitura all’interno o all’esterno del widget in modo che ci sia meno congestione tra i widget, e anche tra il testo del widget e i confini del widget. Ora, sono necessarie opzioni come padx, pady, ipadx e ipadx.

Tkinter Geometry_Pack_Padding.py
import tkinter as tk
    
app = tk.Tk()
app.geometry('300x200')

buttonW = tk.Button(app, text="West")
buttonW.pack(side='left', ipadx=20, padx=30)

buttonE = tk.Button(app, text="East")
buttonE.pack(side='right', ipadx=20, padx=30)

app.mainloop()

Metodo di impaginazione del pacchetto Tkinter - aumentare il riempimento dei widget

Entrambi i pulsanti aggiungono l’imbottitura interna di 20 unità e quella esterna di 30 unità nel x, e l’unità è pixel ma non la larghezza di un carattere.

Tkinter pack Layout di riempimento in direzione x, y

La seguente implementazione del codice potrebbe riempire automaticamente la dimensione del widget alla stessa larghezza o alla stessa altezza della finestra, e quando si ingrandisce la finestra, la dimensione del controllo può cambiare automaticamente con la dimensione della finestra.

Tkinter Geometry_Pack_Fill.py
import tkinter as tk
    
app = tk.Tk()
app.geometry('300x200')

buttonX = tk.Button(app, text="Fill X", bg="red", height=5)
buttonX.pack(fill='x')

buttonY = tk.Button(app, text="Fill Y", bg="green", width=10)
buttonY.pack(side='left', fill='y')

app.mainloop()

Metodo di riempimento del pacchetto Tkinter Layout Metodo di riempimento in direzione X,Y

butonX.pack(fill='x') significa buttonX riempirà la larghezza dell’intera finestra. Allo stesso modo, fill='y' riempirà l’altezza dell’intera finestra, e nel frattempo fill='both' riempirà sia la larghezza che l’altezza.

Tkinter pack Opzione di layout expand - espandi automaticamente

Sopra l’opzione fill= riempirà automaticamente il widget in direzione x e/o y quando la dimensione della finestra viene modificata. Un altro requisito simile è come visualizzare automaticamente tutti i contenuti se il widget include più opzioni, come una lista?

Tkinter Geometry_Pack_Expand.py
import tkinter as tk
import calendar    
    
app = tk.Tk()

buttonX = tk.Button(app, text="Label ", bg="blue", height=5)
buttonX.pack(fill='x')

listboxA = tk.Listbox(app, width=10)
listboxA.pack(fill='both', expand=1)

for i in range(1,13):
    listboxA.insert(tk.END, calendar.month_name[i])
    
app.mainloop()

Il metodo di layout del pacchetto Tkinter abilita l'opzione expand

Quando expand=True o expand=1, la casella di riepilogo elencherà tutti gli elementi, da January a December come dimostrato nell’esempio precedente.

Se expand è impostato su False, allora la casella di riepilogo mostra solo i primi 10 elementi di default. È necessario usare il mouse o i tasti di direzione per mostrare gli elementi nascosti dopo che la casella di riepilogo è stata selezionata.

listboxA.pack(fill='both', expand=0)

expand=0 disabilita la casella di riepilogo per mostrare automaticamente tutti gli elementi.

Metodo di layout del pacchetto Tkinter quando l'opzione expand è disabilitata

Metodo di impaginazione grid di Tkinter

Tkinter grid è un altro e anche il più importante metodo di geometria del layout. Questo è quello che si dovrebbe imparare se si vuole imparare un solo metodo tra tutti i gestori di geometria.

grid è spesso usato nelle finestre di dialogo, e si possono posizionare i widget in base alle coordinate della posizione della griglia. Il metodo “griglia” potrebbe avere posizioni relative stabili di tutti i widget.

L’esempio seguente creerà una GUI relativamente complicata rispetto agli esempi precedenti, che utilizza il maggior numero possibile di opzioni di grid che verranno spiegate nelle prossime sezioni.

Tkinter Geometry_Grid_Basic.py
import tkinter as tk

app = tk.Tk() 

labelWidth = tk.Label(app,
                    text = "Width Ratio")
labelWidth.grid(column=0, row=0, ipadx=5, pady=5, sticky=tk.W+tk.N)

labelHeight = tk.Label(app,
                    text = "Height Ratio")
labelHeight.grid(column=0, row=1, ipadx=5, pady=5, sticky=tk.W+tk.S)


entryWidth = tk.Entry(app, width=20)
entryHeight = tk.Entry(app, width=20)

entryWidth.grid(column=1, row=0, padx=10, pady=5, sticky=tk.N)
entryHeight.grid(column=1, row=1, padx=10, pady=5, sticky=tk.S)


resultButton = tk.Button(app, text = 'Get Result')
resultButton.grid(column=0, row=2, pady=10, sticky=tk.W)

logo = tk.PhotoImage(file='python.gif')
labelLogo = tk.Label(app, image=logo)

labelLogo.grid(row=0, column=2, columnspan=2, rowspan=2,
               sticky=tk.W+tk.E+tk.N+tk.S, padx=5, pady=5)

app.mainloop()

Metodo di layout della griglia di Tkinter

Tkinter grid column e row opzioni

labelWidth.grid(column=0, row=0, ipadx=5, pady=5, sticky=tk.W+tk.N)

Ogni widget deve essere collocato nella cella assoluta nel metodo di impaginazione grid. La coordinata della cella è determinata da colunmn e row.

Il widget labelWidth è posto nella cella della posizione (0, 0). La coordinata inizia dall’angolo in alto a sinistra della finestra.

Le opzioni ipadx, ipady, padx e pady sono le stesse del metodo pack.

L’opzione grid sticky di Tkinter

sticky determina come il widget si attacca alla cella quando il widget è più piccolo della cella.

sticky Significato
W attaccati a sinistra…
E attaccati a destra
N attaccare in cima
S attaccati al fondo

L’opzione predefinita sticky è centrale, cioè W+E+N+S.

Opzioni Tkinter columnspan e rowspan

labelLogo.grid(row=0, column=2, columnspan=2, rowspan=2,
               sticky=tk.W+tk.E+tk.N+tk.S, padx=5, pady=5)

La coordinata di cella del labelLogo è (column=2, row=0) e la dimensione del logo è relativamente grande, quindi è assegnata con una dimensione di cella di 2x2. columnspan=2 e rowspan=2 significa che il widget ha campate di due celle sia in direzione X che Y a partire dalla posizione del widget.

Metodo place di Tkinter

Il metodo place di Tkinter colloca il widget in una posizione assoluta o relativa nella finestra. Usiamo ancora lo stesso approccio di cui sopra per introdurre le opzioni di questo metodo di impaginazione.

Tkinter Geometry_Place_Basic.py
import tkinter as tk

app = tk.Tk()
app.geometry('300x300') 

labelA = tk.Label(app, text = "Label (0, 0)", fg="blue", bg="#FF0")
labelB = tk.Label(app, text = "Label (20, 20)", fg="green", bg="#300")
labelC = tk.Label(app, text = "Label (40, 50)", fg="black", bg="#f03")
labelD = tk.Label(app, text = "Label (0.5, 0.5)", fg="orange", bg="#0ff")

labelA.place(x=0, y=0)
labelB.place(x=20, y=20)
labelC.place(x=40, y=50)
labelD.place(relx=0.5, rely=0.5)

app.mainloop()

Metodo Tkinter Place Layout

Tkinter place Posizione assoluta

labelA.place(x=0, y=0)
labelB.place(x=20, y=20)

Le opzioni x= e y= in place determinano le posizioni assolute del widget, che hanno l’unità come pixel. Per esempio, lableB.place(x=20, y=20) significa che labelB è posto nella coordinata di (20, 20).

Tkinter place Posizione relativa

Lo svantaggio della posizione assoluta è che se ci sono altri widget nella finestra posizionati con posizioni relative, quando la finestra viene ingrandita, il widget che utilizza il layout della posizione assoluta avrà eventualmente la sovrapposizione con altri widget.

Il metodo place layout ha anche l’opzione della posizione relativa, cioè,

labelD.place(relx=0.5, rely=0.5)

Dove relx e rely sono nell’intervallo 0.0~1.0. È la percentuale relativa della posizione del widget rispetto alla dimensione della finestra.

Per esempio, relx=0.5, rely=0.5 significa che il widget è posizionato nel 50% della larghezza della finestra e nel 50% dell’altezza della finestra.

relx=1.0 è il confine destro della finestra, e rely=1.0 è il confine inferiore della finestra.