Tkinter Tutorial - Gestão de Layout

Jinku Hu 30 janeiro 2023
  1. Tkinter pack Método de Layout
  2. Tkinter grid Método de Layout
  3. Tkinter place Método
Tkinter Tutorial - Gestão de Layout

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

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.

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.

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.

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?

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.

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.

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.

Autor: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook