Componentes Tk

Em Python Tkinter, os componentes Tk (ou widgets) são os elementos básicos da interface gráfica, como botões, rótulos, caixas de texto, frames, entre outros. Cada componente é uma classe que representa um widget visual que pode ser criado, configurado e exibido na janela da aplicação.

Hierarquia e criação

Os widgets são organizados numa hierarquia, onde cada widget filho recebe como primeiro argumento o widget pai (geralmente a janela principal ou um frame).

Exemplo:

from tkinter import *

root = Tk()  # janela principal

frame = Frame(root)
frame.pack()

label = Label(frame, text="Olá, Tkinter!")
label.pack()

button = Button(frame, text="Clique aqui")
button.pack()

root.mainloop()

Configuração e layout

Cada widget possui opções configuráveis, como texto, fonte, cor, tamanho, e métodos para posicionamento, como pack()grid(), e place()

A configuração de um componente é feita usando opções no formato opção=valor. Essas opções controlam a aparência e o comportamento do componente.

Podemos configurar um componente em dois momentos:

  • No momento da criação do componente, passando uma lista de uma ou mais opções com os respetivos valores no construtor do componente:
label = Label(mainWindow, text="Label de exemplo", bg="black", fg="white", height="2", width="20")
  • Após a criação do componente, usando o método .config() ou .configure(), passando-lhe uma lista de uma ou mais opções com os respectivos valores:
label = Label(mainWindow, text="Label de exemplo") 
label.config(bg="black", fg="white") 
label.config(height="2") 
label.config(width="20")

As opções de configuração de um componente possuem valores de defeito que, na maioria dos casos, são perfeitamente ajustadas às situações mais comuns pelo que, para a maioria delas, não há sequer necessidade de alterar esses valores.

Se chamarmos o método .config() ou .configure() sem argumentos receberemos um dicionário com todas as opções correntes, valores de defeito e valores correntes.

Para obter o valor atual de uma determinada opção usamos o método .cget():

chk = Checkbutton(window, text="On", indicator=0)
chk.pack()

#mostra o valor atual da opção 'text':
print(chk.cget('text'))

Output:

On

Podemos obter uma lista de todas as opções permitidas para um componente usando o método .keys():

window = Tk()

def greet():
    print("Greetings!")

chk = Checkbutton(window, text="On", indicator=0)
chk.pack()

#obtém a lista de todas as opções permitidas:
print( chk.keys() )

O output será:

['activebackground', 'activeforeground', 'anchor', 'background', 'bd', 'bg', 'bitmap', 'borderwidth', 'command', 
'compound', 'cursor', 'disabledforeground', 'fg', 'font', 'foreground', 'height', 'highlightbackground',
'highlightcolor', 'highlightthickness', 'image', 'indicatoron', 'justify', 'offrelief', 'offvalue', 'onvalue',
'overrelief', 'padx', 'pady', 'relief', 'selectcolor', 'selectimage', 'state', 'takefocus', 'text', 'textvariable',
'tristateimage', 'tristatevalue', 'underline', 'variable', 'width', 'wraplength']

Aparência de um componente

Por configuração, podemos alterar a aparência de um componente em vários aspectos tais como:

  • Dimensão
  • Cor de fundo e de texto.
  • Espessura da borda.
  • Relevo.
  • Fonte, tamanho e estilo do texto.
  • Foco sobre o componente.
  • Cursor.

Dimensão

As opções width e height permitem definir a largura e altura de um componente.

No caso dos componentes baseados em texto, como Label, Entry, Button, Text ou Listbox, width, por exemplo, é expressa em termos de carateres enquanto height é expressa em termos de linhas de texto. No caso dos restantes componentes, width e height são expressas em pixeis.

O modo como as dimensões são definidas pode ser vista na secção Dimensões.

Cor de fundo e de texto

A cor de fundo é definida usando a opção background ou o seu alias bg.

A cor de texto é definida usando a opção foreground ou o seu alias fg.

O modo como as cores são definidas pode ser vista na secção Cores.

Espessura da borda

A espessura da borda é normalmente, por defeito, de 2 pixeis. Para alterar este valor, usa-se a opção borderwidth ou o seu alias bd.

Relevo

O tipo de relevo de um componente é definido com a opção relief.

As diferentes opções de relevo que se podem usar nesta opção, podem ser vistas na secção Relevo.

Fonte, tamanho e estilo do texto

A opção font permite definir a fonte, o tamanho e o estilo do texto.

Ver a secção Fontes para mais informações.

Foco sobre o componente

Quando um componente recebe o foco do teclado, podemos alterar o aspeto da região de foco através de 3 opções:

  • highlightcolor
  • highlightbackground
  • highlightthickness

Para mais informações sobre as opções, ver a secção Foco

Cursor

Podemos mudar o icon do cursor, quando o rato está sobre o componente, através da opção cursor.

Para mais informações sobre os diferentes tipos de cursores que podem ser usados nesta opção, ver a secção Cursor.

Classes StringVar e IntVar

As classes StringVar e IntVar em Python Tkinter são tipos especiais de variáveis criadas para facilitar a ligação dinâmica entre os valores de componentes (como EntryLabelCheckbutton, etc.) e o código Python. Elas são fundamentais para o funcionamento reativo das interfaces gráficas feitas com Tkinter.

  • Ambas possuem métodos .get() para obter o valor atual e .set(valor) para definir um novo valor.
  • São essenciais para a comunicação entre componentes e o código, permitindo interfaces mais dinâmicas e reativas sem a necessidade de manipular diretamente o texto ou valor dos componentes em cada evento.
  • Existem outras classes similares, como BooleanVar e DoubleVar, para tipos booleanos e ponto flutuante, respetivamente.

StringVar

  • O que é: É uma classe que armazena valores do tipo string.
  • Para que serve: Permite associar o valor de componentes de texto (como Entry ou Label) a uma variável Python. Sempre que o valor da variável muda, o componente é atualizado automaticamente, e vice-versa. Isso simplifica a leitura e atualização do conteúdo em componentes de texto.

Exemplo:

import tkinter as tk

root = tk.Tk()

nome_var = tk.StringVar()

entry = tk.Entry(root, textvariable=nome_var)
entry.pack()
label = tk.Label(root, textvariable=nome_var)
label.pack()

root.mainloop()

Neste exemplo, ao digitar no campo de entrada, o texto do Label é atualizado automaticamente.

IntVar

  • O que é: Uma classe que armazena valores inteiros.
  • Para que serve: Usada para associar valores inteiros de componentes, como campos numéricos, botões de rádio ou checkboxes, a variáveis Python. Isso permite ler e alterar valores de componentes de forma dinâmica e sincronizada.

Exemplo:

import tkinter as tk

root = tk.Tk()
int_var = tk.IntVar()
entry = tk.Entry(root, textvariable=int_var)
entry.pack()
label = tk.Label(root, textvariable=int_var)
label.pack()
root.mainloop()

Neste exemplo, ao alterar o valor no Entry, o Label é atualizado automaticamente

Métodos comuns a todos os componentes

Para além dos métodos próprios de cada componente, existe um conjunto de métodos que são comuns a todos componentes que podemos ver na lista abaixo:

.after(delay_ms, callback=None, *args) : Chama a função especificada no argumento callback, passando os argumentos args, após um atraso de delay_ms milisegundos.

Se se chamar este método sem especificar a função de callback, este método espera delay_ms milisegundos.

Este método retorna um valor inteiro que pode ser pasado ao método .after_cancel() de forma a cancelar a chamada de callback.

delay_ms: Número de milisegindos após os quais a função callback é chamada.

callback: Função a ser chamada.

*args: Argumentos a serem passados para a função.

.after_cancel(id) : Cancela o pedido de callback feito com o método .after().

id: Valor retornado pelo método .after() quando se fez o pedido de callback.

.after_idle(func, *args) : Faz um pedido para que o Tkinter execute a função especificada em func>, passando os argumentos args, da próxima vez que o sistema estiver parado (sem eventos para processar). Esta função só será chamada uma vez.

func: Função a ser chamada.

*args: Argumentos da função.

.beep() : Emite um som ‘bip’.

.bind(event=None, func=None, add=None) : Anexa uma ligação de evento (bind) ao componente para o evento event. Quando esse evento ocorrer, chama a função definida em func. Se já existir uma ligação para este evento, é substituída. Se pretendermos mantê-la e adicionar esta, passamos ‘+’ no argumento add.

event: Evento em relação ao qual vamos estebelecer uma ligação de evento para este componente.

func: Função de callback a ser chamada quando o evento ocorrer.

add: ‘+’, se pretendermos adicionar esta ligação a outras já existentes para o evento.

.bind_all(event=None, func=None, add=None) : Igual a .bind() só que se aplica a todos os componentes da aplicação.

event: Evento em relação ao qual vamos estebelecer uma ligação de evento para este componente.

func: Função de callback a ser chamada quando o evento ocorrer.

add: ‘+’, se pretendermos adicionar esta ligação a outras já existentes para o evento.

.bind_class(className, evento=None, func=None, add=None) : Igual a .bind() só que se aplica aos componentes de uma determinada classe (Button, Entry, etc..).

className: Classe do componente.

event: Evento em relação ao qual vamos estebelecer uma ligação de evento para este componente.

func: Função de callback a ser chamada quando o evento ocorrer.

add: ‘+’, se pretendermos adicionar esta ligação a outras já existentes para o evento.

.bindtags(tagList=None) : As bindtags de um componente representam a ordem pela qual os eventos associados a este componente são chamados. Este método retorna aa bindtags do componente. Se chamado com uma lista de bindtags podemos alterar essa ordem de acordo com a lista.

tagList: Lista de bindtags a ser associada ao componente.

.cget(option) : Retorna uma string com o valor da opção option.

option: Nome da opção de que se quer obter o valor.

.clipboard_append(text) : Adiciona o texto text ao clipboard.

text: Texto a ser adicionado ao clipboard.

.clipboard_clear() : Limpa os dados do clipboard.

.config(option=value,…) : Define o valor de uma ou mais opções de configuração do componente.

option: Par option=value com o valor da opção a alterar.

.configure(option=value,…) : O mesmo que .config().

option: Par option=value com o valor da opção a alterar.

.destroy() : Destrói o componente e todos os seus filhos.

.event_add(virtual_evt, *seqs) : Cria um evento virtual com o nome virtual_evt para o evento seq. Quando o(s) evento(s) seqs ocorrer(em), o evento virtual é despoletado.

virtual_evt: String com o nome do evento virtual.

seqs: Evento(s) reais ligado(s) ao evento virtual .

.event_delete(virtual_evt, *seqs) : Remove os eventos reais do evento virtual virtual_evt. Quando todos os eventos reais forem removidos o evento virtual desaparece.

virtual_evt: String com o nome do evento virtual.

seqs: Evento(s) reais ligado(s) ao evento virtual .

.event_generate(seq, **keyword) : Despoleta o evento seq. Podemos fornecer valores para campos do objeto Event através de argumentos do tipo keyword=value onde keyword é o nime de um campo do objeto Event.

seq: Evento a ser despoletado.

**keyword: Pares keyword=value para passar valores aos campos keyword do objeto Event.

.event_info(virtual_evt=None) : Sem argumento obtém uma lista com os nomes de todos os eventos virtuais definidos. Com virtual_evt igual ao nome de um evento virtual, obtém uma sequência com todos os eventos reais associados a esse evento virtual, ou None se o evento virtual não esta definido.

virtual_evt: Nome de um evento virtual.

.focus_displayof() : Retorna o nome da janela que tem o foco, na mesma visualização do componente. Se não houver nenhuma, retorna None.

.focus_force() : Força o foco de input do componente.

.focus_get() : Retorna o componente que tem o foco na aplicação. None se não houver nenhum.

.focus_lastfor() : Retorna o nome do componente que teve o foco pela última vez na janela de toplevel do componente. Se nenhum componente dessa janela alguma vez teve o foco, retorna o nome da janela. Se a aplicação não tem o foco, retorna o nome do componente que terá o foco quando este estiver na aplicação.

.focus_set() : Atribui o foco ao componente, se a aplicação tiver o foco. Se não tiver, atribuirá o foco ao componente assim que a aplicação tiver o foco.

.grab_current() : Retorna o componente que tem o grab nesta aplicação. Retorna None se não houver nenhum.

.grab_release() : Liberta o grab, se estiver definido, para este componente.

.grab_set() : Define grab para este componente. O grab irá desviar todos os eventos para este componente e para os seus filhos.

.grab_set_global() : Define um grab global para este componente. Isto fará com que todos os eventos sejam redirecionados para o componente e seus filhos. Outras aplicações deixarão de receber eventos.

.grab_status() : Retorna “local”, “global” ou None se houver um grab local, global ou não houver nenhum grab para este componente.

.grid_forget() : serve para ocultar temporariamente um componente que foi posicionado usando o gestor de layout grid. Ao chamar widget.grid_forget(), o componente desaparece da interface, mas não é destruído nem removido da memória; ele apenas deixa de ser exibido.

.grid_propagate() : controla se o tamanho de um componente contentor (como um Frame) deve se ajustar automaticamente ao tamanho dos seus componentes filhos quando se utiliza o gestor de geometria grid.

Por padrão, a propagação está ativada (grid_propagate(True)), o que significa que o contentor ajusta seu tamanho para acomodar exatamente os componentes internos.
Quando a propagação é desativada (grid_propagate(False)), o contentor mantém o tamanho que você definiu manualmente (por exemplo, via width e height), mesmo que os componentes internos sejam maiores ou menores

.grid_remove() : serve para ocultar temporariamente um componente posicionado com o gestor de layout grid, mantendo todas as suas configurações originais (como linha, coluna, sticky, padx, pady, etc.). Isso permite restaurar o componente exatamente na mesma posição e com as mesmas opções simplesmente chamando grid() novamente, sem precisar informar novamente os parâmetros.

Principais características:

Restauração fácil: basta chamar widget.grid() para reexibi-lo no mesmo lugar e com as mesmas configurações.

Oculta o widget da interface sem destruí-lo.

Mantém as configurações do grid (posição e opções).

.image_names() : Retorna uma sequência de strings com os nomes de todas as imagens da aplicação.

.keys() : Retorna uma sequência de strings com os nomes das opções do componente.

.lift(aboveThis=None) : Sem argumento, move a janela a que pertence o componente para o topo da pilha de janelas. Com argumento, move a janela a que pertence o componente para cima da janela referenciada por aboveThis.

aboveThis: Janela de referência.

.lower(belowThis=None) : Sem argumento, move a janela a que pertence o componente para o fundo da pilha de janelas. Com argumento, move a janela a que pertence o componente para baixo da janela referenciada por aboveThis.

belowThis: Janela de referência.

.mainloop() : Este método processa os eventos de uma janela e deve ser chamado logo após a criação de todos os componentes.

.nametowidget(name) : Retorna o objeto do componente cujo nome é name. Se o nome fôr descionhecido, levanta o erro KeyError.

name: nome do componente.

.option_add(pattern, value, priority=None) : Define valores de defeito para as oções de um ou mais componentes.

pattern: string que define a opção para um ou mais componentes.

value: valor de defeito.

priority: nivel de prioridade. Pode ser um dos seguintes valores:

  • 20: valores de defeito globais dos componentes
  • 40: valores de defeito de aplicações específicas.
  • 60: para opções de venham de ficheiros tais como o ficheiro Xdefaults.
  • 80: para opções definidas quando a aplicação arranca. É o nivel de prioriudade de defeito.

.option_clear() : Remove todas as opções da base de dados de opções. Tem como efeito restaurar todos os valores de defeito.

.option_get(name, classname) : Obtém o valor de uma opção da base de dados de opções do Tkinter. Se não houver uma correspondência retorna ”.

name: Nome da instância.

classname: Nome da classe.

.option_readfile(filename, priority=None) : Podemos armazenar as opções de configuração num ficheiro com o mesmo formato do ficheiro .Xdefaults. Depois, quando a aplicação se inicializa, passamos o nome do ficheiro de configuração para este método e as opções nele contidas serão adicionadas à base de dados de opções.

filename: Nome do ficheiro de configuração.

priority: Opcional. Prioridade.

.register(function) : Este método cria um invólucro (wrapper) de Tcl à volta de uma função de Python e retorna o nome do invólucro de Tcl como uma string.

function: Função à volta da qual irá ser criado um invólucro de Tcl.

.quit() : Este método faz com que a aplicação saia do mainloop.

.rowconfigure(index, opcoes) : Configura a linha com o indíce index usando uma lista de opções no formato opcao=valor. Opções válias são minsize (tamanho mínimo em pixeis), pad (quantidade de espaço extra à volta da linha) e weight (de que forma espaço extra se propaga a esta linha).

.selection_clear() : Limpa qualquer seleção existente no componente.

.selection_get() : Se o componente tem uma seleção, retorna o conteúdo desa seleção. Se o componente não tem qualquer seleção, levanta a exceção tk.TclError.

.selection_own() : Torna o componente dono da seleção correntemente em visualização.

.selection_own_get() : Retorna o componente dono da seleção visualizada. Levanta a exceção tk.TclError se não houver seleção.

.tk_focusFollowsMouse() : Faz com que o componente sobre o qual o rato esteja ganhe o foco. Este comportamento não é fácilmente desabilitado.

.tk_focusNext() : Retorna o componente que se segue a este componente na ordem do foco.

.tk_focusPrev() : Retorna o componente que precede este componente na ordem do foco.

.unbind(sequence, func=None) : Elimina as ligações (bindings) ao componente para o evento descrito por sequence. Se func é uma função de callback ligada a esta sequência será eliminada, ficando tudo o resto. Se func fôr omitida, todas as ligações serão eliminadas.

sequence: Sequência de evento ligada.

func: Opcional. Função de callback ligada à sequência.

.unbind_all(sequence) : Elimina todas a ligações de evento, na aplicação, para o evento descrito por sequence.

sequence: Sequência de evento ligada.

.unbind_class(className, sequence) : Igual a .unbind() mas aplica-se a todos os componentes da classe className.

className: Classe do componente.

sequence: Sequência de evento.

.update() : Força uma actualização do display. Pode conduzir a resultados imprevisíveis. Nunca deve ser chamado a partir de uma função de callback de um evento ou de uma função chamada por uma função de callback de um evento.

.update_idletasks() : Força uma actualização do display para tarefas chamadas de idle tasks, tais como redimensionamento e redesenho de componentes, tarefas que são normalmente adiadas até que o sistema trate todos os eventos e regrese ao main loop.

.wait_variable(v) : Espera até que à variável v seja atribuido um valor, mesmo que indefinidamente. Este método entra num loop local pelo que não bloqueia o resto da aplicação.

v: Variável.

.wait_visibility(c) : Espera até que o componente c (normalmente uma janela Topevel esteja visível.

c: Componente.

.wait_window(w) : Espera até que a janela w seja destruída.

x: Componente.

.winfo_children() : Retorna uma lista de todos os componentes filhos do componente na ordem porque estão na pilha, desde o que está no fundo até ao que está no topo.

.winfo_class() : Retorna a classe do componente.

.winfo_containing(rootX, rootY, displayof=0) : Procura a janela que comtém o ponto de coordenadas rootX, rootY. Se displayof é falso, as coordenadas são relativas à janela principal da aplicação. Se fôr verdadeiro, as coordenadas são relativas à janela de Toplevel que contém o componente. Retorna a janela que contém o ponto, senão retorna None.

rootX, rootY: Coordenadas do ponto.

displayof: Indicador de em que janela deve procurar o ponto.

.winfo_depth() : Retorna o número de bits por pixel na área de visualização do componente.

.winfo_fpixels(number) : Retorna um float com a distância em pixeis, para um valor de dimensão number, na área de visualização do componente.

number: Valor de uma dimensão.

.winfo_geometry() : Retorna uma string de geometria, na forma “larguraxaltura+X+Y”, com a dimensão e localização do componente.

.winfo_height() : Retorna a altura do componente em pixeis.

.winfo_id() : Retorna um inteiro que identificade forma única o componente na janela a que pertence. Este valor é necesário para o método .winfo_pathname().

.winfo_ismapped() : Retorna True se a janela está mapeada, ou seja, incorporada no seu pai através de .pack(), .grid() ou outro gestor de layout, e se o seu componente pai está incorporado no seu componente pai e asim sucesivamente até à janela toplevel.

.winfo_manager() : Retorna uma string vazia se o componente não foi incorporado no seu componente pai, via .pack(), .grid() ou outro gestor de layout. Se foi retorna uma string com o gestor de layout. Neste caso, valores retornados podem ser ‘grid’, ‘pack’, ‘place’, ‘canvas’, ou ‘text’.

.winfo_name() : Retorna o nome do componente relativo ao seu componente pai.

.winfo_parent() : Retorna o caminho do componente ou uma string vazia se o componente é uma janela toplevel.

.w.winfo_pathname(id, displayof=0) : Se o argumento displayof é falso, retorna o caminho do componente com o indicador de identificação id na janela principal da aplicação. Se displayof é verdadeiro, o número id especifica um componente na mesma janela que este componente.

id: Numero de identicação único.

displayof: Indicador de componente.

.winfo_pixels(number) : Retorna um inteiro com a distância em pixeis, para um valor de dimensão number, na área de visualização do componente.

number: Valor de uma dimensão.

.winfo_pointerx() : Retorna a coordenada dos ‘x’, da posição do apontador do rato relativas à janela do componente, ou -1 se o apontador não estiver no mesmo ecran.

.winfo_pointerxy() : Retorna um tuplo (x, y) com as coordenadas da posição do apontador do rato relativas à janela do componente, ou -1 se o apontador não estiver no mesmo ecran.

.winfo_pointery() : Retorna a coordenada dos ‘y’, da posição do apontador do rato relativas à janela do componente, ou -1 se o apontador não estiver no mesmo ecran.

.winfo_reqheight() : Retorna a altura do componente. É a altura mínima necessária para que o seu conteúdo tenha espaço suficiente. A altura real pode ser diferente devido a negociações com o seu gestor de layout.

.winfo_reqwidth() : Retorna a largura do componente. É a largura mínima necessária para que o seu conteúdo tenha espaço suficiente. A largura real pode ser diferente devido a negociações com o seu gestor de layout.

.winfo_rgb(color) : Retorna um tuplo (r, g, b) com os valores rg e b com valores que variam entre 0 e 65536.

Color: Cor, por exemplo ‘red’.

.winfo_rootx() : Retorna a coordenada x do lado esquerdo do componente relativamente à janela a que pertence. Se o componente tem uma borda conta o lado exterior da borda.

.winfo_rooty() : Retorna a coordenada y do topo do componente relativamente à janela a que pertence. Se o componente tem uma borda conta o lado exterior da borda.

.winfo_screenheight() : Retorna a altura do ecran em pixeis.

.winfo_screenmmheight() : Retorna a altura do ecran em milímetros.

.winfo_screenmmwidth() : Retorna a largura do ecran em milímetros.

.winfo_screenvisual() : Retorna uma string que descreve o método de visualização das cores. Normalmente, é ‘truecolor’ para 16- or 24-bit ecrans, ‘pseudocolor’ for ecrans 256-cores.

.winfo_screenwidth() : Retorna a largura do ecran em pixeis.

.winfo_toplevel() : Retorna a janela de toplevel que contém o componente.

.winfo_viewable() : Retorna True se o componente é visível, ou seja, se ele e os seus componentes ancestrais estão incorporados.

.winfo_width() : Retorna a largura do componente em pixeis.

.winfo_x() : Retorna a coordenada dos x do lado esquerdo do componente relativamente ao seu componente pai. Se o componente tem uma borda conta o lado exterior da borda.

.winfo_x() : Retorna a coordenada dos y do topo do componente relativamente ao seu componente pai. Se o componente tem uma borda conta o lado exterior da borda.