Tkinter Tutorial - Gestão de Layout

  1. Tkinter pack Método de Layout
  2. Tkinter grid Método de Layout
  3. Tkinter place Método

Nas seções anteriores, introduzimos vários tipos de widgets Tkinter, tais como label, button, menu drop-down, etc. Enquanto isso, também mencionamos brevemente como dispor estes widgets na janela do programa. Este é o ponto chave que você aprenderá nesta seção - os métodos de gerenciamento geométrico do Tkinter.

Tkinter tem três métodos de gerenciamento geométrico, ou seja, pack, grid, e place. Vamos passar por eles um a um.

Tkinter pack Método de Layout

O método pack, como literalmente indicado, embala o widget na moldura da janela após a sua criação. Encontramos este método de layout na seção Tkinter Label onde todas as opções pack também são listadas.

Nós mostraremos a você como fazer o layout de widgets com o método pack (também suas opções). Alguns exemplos ajudam a demonstrar a configuração correta.

Tkinter pack Layout - Posição 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()

Execute o programa, você terá uma janela como esta,

Método de layout da embalagem Tkinter - posição relativa do lado

Como você pode ver, buttonWest se encaixa no lado esquerdo da janela e buttonEast se encaixa no lado direito da janela. Você pode tentar escalar o tamanho da janela abaixo, mas você verá que eles ainda se agarram aos lados da janela e a posição relativa não mudará.

buttonW.pack(side='left')

O side tem quatro opções -

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

Ele coloca o widget no side da janela. Como ilustrado no exemplo, buttonW é alocado no lado esquerdo da janela, porque side='left', enquanto buttonE está no lado direito da janela, porque side='right'.

Agora temos um cenário interessante, o que acontece se dois widgets tiverem a mesma propriedade side, como será o layout?

Tente respondê-lo você mesmo, ou verifique executando os seguintes códigos.

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 para adicionar um widget com preenchimento interno e externo

Em alguns casos, você precisa adicionar algum acolchoamento dentro ou fora do widget para que haja menos congestionamento entre os widgets, e também entre o texto do widget e os limites do widget. Agora, você precisa de opções como 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()

Tkinter método de layout de pacotes - aumentar o preenchimento de widgets

Ambos os botões adicionam 20 unidades internas e 30 unidades externas no x, e a unidade é pixel, mas não a largura de um caractere.

Tkinter pack Layout Preenchimento em direção x, y

A implementação do seguinte código pode preencher automaticamente a dimensão do widget com a mesma largura ou altura da janela, e quando você ampliar a janela, o tamanho do controle pode mudar automaticamente com o tamanho da janela.

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()

Tkinter Pack Método de Layout Preenchimento na Direção X,Y

O butonX.pack(fill='x') significa que o buttonX irá preencher a largura de toda a janela. Da mesma forma, fill='y' irá preencher a altura de toda a janela, e enquanto isso fill='ambos' irá preencher tanto a largura quanto a altura.

Tkinter pack Opção de layout expand - expande automaticamente

Acima da opção fill= preencherá automaticamente o widget na direção x e/ou y quando o tamanho da janela for modificado. Outro requisito similar é como exibir automaticamente todo o conteúdo se o widget inclui múltiplas opções, como uma 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()

O método de layout do pacote Tkinter permite expandir a opção

Quando expand=True ou expand=1, a caixa de listagem irá listar todos os itens, de January a December, como demonstrado no exemplo acima.

Se expand estiver definido para False, então a caixa de listagem mostra apenas os primeiros 10 itens por padrão. Você precisa usar o mouse ou as teclas de direção para mostrar os itens escondidos depois que a caixa de listagem for selecionada.

listboxA.pack(preencha='ambos', expanda=0)

expand = 0 desactiva a caixa de listagem para mostrar automaticamente todos os itens.

O método de layout do pacote Tkinter quando a opção expandir está desativada

Tkinter grid Método de Layout

Tkinter grid é outro e também o mais importante método de geometria de layout. Este é o que você deve aprender se quiser aprender apenas um único método entre todos os gerenciadores de geometria.

A grid é frequentemente utilizada em caixas de diálogo, e você poderia colocar os widgets com base nas coordenadas de posição da grade. O método de layout grid pode ter posições relativas estáveis de todos os widgets.

O exemplo seguinte irá criar uma GUI relativamente complicada em comparação com os exemplos acima, que utiliza o maior número possível de opções de grid que serão explicadas nas próximas seções.

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()

Método de layout de grade Tkinter

Tkinter grid column e row opções

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

Cada widget deve ser colocado na célula absoluta no método de layout grid. A coordenada da célula é determinada por column e row.

A widget labelWidth é colocada na célula da posição (0, 0). A coordenada começa a partir do canto superior esquerdo da janela.

As opções ipadx, ipady, padx e pady são as mesmas que as do método pack.

Tkinter grid opção sticky

O sticky determina como o widget se cola à célula quando o widget é menor que a célula.

sticky Significado
W virar à esquerda
E ater-se à direita
N limitar-se ao topo
S ater-se ao fundo

A opção padrão sticky é centro, ou seja, W+E+N+S.

Tkinter columnspan e rowspan opções

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

A coordenada da célula do labelLogo é (column=2, row=0) e o tamanho do logotipo é relativamente grande, portanto é alocado com o tamanho da célula de 2x2. columnspan=2 e rowspan=2 significa que o widget tem intervalos de duas células tanto em X como em Y, começando a partir da posição do widget.

Tkinter place Método

O método Tkinter place coloca o widget em uma posição absoluta ou relativa na janela. Ainda utilizamos a mesma abordagem acima para introduzir as opções deste método de layout.

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()

Método Tkinter Place Layout

Tkinter place Posição Absoluta

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

As opções x= e y= em place determinam as posições absolutas do widget, que tem a unidade como pixel. Por exemplo, lableB.place(x=20, y=20) significa que labelB é colocado na coordenada de (20, 20).

Tkinter place Posição Relativa

A desvantagem da posição absoluta é que se houver outros widgets na janela colocados com posições relativas, quando a janela for ampliada, o widget usando o layout de posição absoluta terá possivelmente a sobreposição com outros widgets.

O método de layout place também tem a opção de posição relativa, ou seja,

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

Onde relx e rely estão na faixa de 0.0~1.0. É a percentagem relativa da posição do widget para o tamanho da janela.

Por exemplo, relx=0.5, rely=0.5 significa que o widget é colocado nos 50% da largura da janela e 50% da altura da janela.

relx=1.0 é o limite direito da janela, e rely=1.0 é o limite inferior da janela.