Tutorial Python Tkinter
Por Abner Matheus Costa de Araújo
(abner.araujo@ccc.ufcg.edu.br)
Neste tutorial aprenderemos a manipular a biblioteca de interface gráfica padrão do Python: O Tkinter. Você está preparado para esta viagem?

Todo graduando em Ciência da Computação da UFCG se depara com Python pelo menos uma vez em sua vida. Após o primeiro período, Python é abandonado em favor de outras linguagens, como Java. Mas não se engane! Nem por isso Python é menos poderoso. Embora sua aplicação mais usual seja para backend de sistemas web utilizando o framework Djando, ele pode sim ser utilizado para aplicações desktop, pois, assim como Java, ele também possui uma máquina virtual.


Como forma de demonstrar a utilidade do Python em aplicações desktop, vamos aqui abordar a biblioteca padrão do Python para interfaces gráficas: O Tkinter.


Obs: Tkinter já vem instalado junto com o Python se você estiver usando a versão para Windows. Se estiver usando Linux/Mac, você precisa instalá-lo manualmente, o que pode ser feito de maneira muito fácil aqui.




Criando nossa primeira janela

O primeiro passo é importar as classes necessárias. Geralmente todas elas estão dentro do módulo Tkinter:


Código:

from Tkinter import *


E para fazê-la funcionar, de fato, precisamos rodá-la numa thread utilizando o método mainloop.


Código:

from Tkinter import *


janela = Tk()

janela.mainloop()


Com isto já estamos aptos a enxergar nossa janela:



Como o método mainloop trava a thread onde foi chamado, nenhum código que está abaixo da chamada do método vai ser executado até que a janela seja fechada.

Mais a frente aprenderemos a usar os event handlers para contornar esse problema.



Decorando nossa janela

Uma janela vazia não é de muita serventia, não é verdade? :-)

Vamos aprender a preencher nossa janela com conteúdo!


Claro, não podemos inserir os elementos de qualquer forma, para isso precisamos entender um pouco de containers.


Container assume um papel semelhante aos Layouts do Swing: Eles servem para organizar os elementos na tela. O mais simples deles é o Frame, que é o que vamos utilizá-lo.


Então vamos criar um Frame onde iremos inserir elementos (também chamados de widgets) dentro dele:


Código:

from Tkinter import *


janela = Tk()

frame1 = Frame(janela)

janela.mainloop()


Perceba que o construtor da classe Frame espera como parâmetro uma instância da classe Tk. Faz sentido! Outra coisa a se perceber é que criei a instância antes da chamada do método mainloop (por causa daquele problema do travamento da thread…).


Toda vez que for inserir algo na janela, seja um container ou widget, é importante chamar o método pack. O que este método faz é anexar o elemento à janela. Caso não o chame, o elemento não será visível.


Código:

from Tkinter import *


janela = Tk()

frame1 = Frame(janela)

frame1.pack()

janela.mainloop()


Agora vamos adicionar um botão à nossa janela! Para isto, veja as modificações que fiz:


Código:

from Tkinter import *


janela = Tk()

frame1 = Frame(janela)

frame1.pack()

botao = Button(frame1, text=”Clique em mim!”)

botao.pack()

janela.mainloop()


Parece simples, não? (<3 Python)

O que fizemos foi criar uma instância da classe Button passando como parâmetros o container dele (no nosso caso, o frame1) e um parâmetro opcional chamado text, que irá definir a mensagem do botão. Rodando nosso código, temos o seguinte comportamento:



Sounds good! Você ainda pode customizar o botão com os atributos que esta classe oferece. Por exemplo, veja o seguinte código:


Código:

from Tkinter import *


janela = Tk()

frame1 = Frame(janela)

frame1.pack()

botao = Button(frame1, text=”Clique em mim!”)

botao[‘width’] = 100

botao.pack()

janela.mainloop()


O código acima irá resultar numa janela de largura bem maior do que a anterior. O que fizemos foi alterar o atributo “width” do Button, mudando-o para 100 (números de caracteres).

Existem muitos outros atributos! Você pode descobrir todos eles digitando help(“Tkinter.Button”) no interpretador do Python.




Posicionando os elementos na tela

Se você fizer o experimento de adicionar mais um botão na tela, verá que ele irá se posicionar exatamente abaixo do anterior. Esse é o comportamento padrão. Mas e se quiséssemos posicionar um botão do lado do outro?


O container Frame suporta quatro tipos de posicionamentos: LEFT, RIGHT, TOP e BOTTOM.

Você pode definir o tipo de posicionamento na hora da chamada do método ‘pack’, da seguinte forma:


Código:

from Tkinter import *


janela = Tk()

frame1 = Frame(janela)

frame1.pack()

botao = Button(frame1, text=”Clique em mim!”)

botao.pack(side=LEFT)

janela.mainloop()


Então se quiséssemos colocar um botão do lado do outro, basta criar dois botões normalmente, mas na hora de dar “pack”, faríamos com que um tivesse side como LEFT e outro como RIGHT, da seguinte forma:


Código:

from Tkinter import *


janela = Tk()

frame1 = Frame(janela)

frame1.pack()

botao1 = Button(frame1, text=”Clique em mim!”)

botao1.pack(side=LEFT)

botao2 = Button(frame1, text=”Eu sou o botão 2!”)

botao2.pack(side=RIGHT)

janela.mainloop()


Rodando nosso código, temos o seguinte resultado:



Este raciocínio pode ser estendido para alinhamento de containers também, da mesmíssima forma que acontece em outras bibliotecas de interface gráfica.



Event handlers

Temos um botão! Mas ele não faz nada :’(

Por nossa sorte eventos no Tkinter são beeeem mais simples do que no Swing (Java), já que não precisamos manipular classes anônimas e essas coisas todas.


Para criar um evento associado a um widget, utilizamos o método “bind”, que recebe dois parâmetros: A ação e o método que será chamado quando a ação for executada. Veja o exemplo:


Código:

from Tkinter import *


janela = Tk()

frame1 = Frame(janela)

frame1.pack()

botao = Button(frame1, text=”Clique em mim!”)

botao.bind(, clica_botao)

botao.pack()

janela.mainloop()


No código acima, a ação é “”, que é a ação correspondente a clicar com o mouse no widget, nesse caso, clicar no botão, e o método que irá ser chamado ao fazer isto é o clica_botao (devido ao paradigma funcional que Python adota, podemos passar funções como parâmetros :-D. Isso não é fantástico?)


Vamos agora construir esta função:


Código:

from Tkinter import *


def clica_botao(event):

    pass


janela = Tk()

frame1 = Frame(janela)

frame1.pack()

botao = Button(frame1, text=”Clique em mim!”)

botao.bind(, clica_botao)

botao.pack()

janela.mainloop()


Perceba que a função recebe como parâmetro um event, do qual podemos extrair informações importantes, como a ação que executou aquele método (quando ele está mapeado para várias ações ou várias teclas, por exemplo…).


Vamos agora importar a classe “tkMessageBox” para mostrar uma caixa de mensagem na tela de maneira rápida.


Código:

from Tkinter import *

import tkMessageBox


def clica_botao(event):

    pass


janela = Tk()

frame1 = Frame(janela)

frame1.pack()

botao = Button(frame1, text=”Clique em mim!”)

botao.bind(, clica_botao)

botao.pack()

janela.mainloop()


E aí vamos usar o tkMessageBox para mostrar ao usuário quais eram as coordenadas do mouse quando ele clicou no botão:


Código:

from Tkinter import *

import tkMessageBox


def clica_botao(event):

    tkMessageBox.showinfo("titulo", "Vc clicou na posicao (%d, %d) da tela" % (event.x, event.y))


janela = Tk()

frame1 = Frame(janela)

frame1.pack()

botao = Button(frame1, text=”Clique em mim!”)

botao.bind(, clica_botao)

botao.pack()

janela.mainloop()


Rodando, temos o seguinte resultado:



Claro, existem muitos outros atributos mais interessantes que saber as coordenadas do mouse. Um bom site para encontrar mais propriedades é este.




Conclusão

Claro, não fizemos uma abordagem extensiva da biblioteca, não era o objetivo aqui. O importante é você conhecer a estrutura básica e ir incrementando seu conhecimento. Existem muitos outros widgets interessantes além de Button: Labels, imagens, canvas, enfim… São muitos! Essa ferramenta é realmente poderosa. Esperamos que você tenha saído deste tutorial com uma visão ainda mais positiva em relação ao Python! :-D


E agora, vamos a um pequeno questionário para testar seu conhecimento. Está preparado?


Perguntas

1. Qual a classe responsável por criar uma janela?

2. O que é um container? E um widget?

3. Para que serve o método “pack”? Como posso usá-lo para posicionar elementos na tela?

4. Para que serve o método bind?


Respostas:

1. É a Tk.

2. Container é um tipo especial de widget responsável por organizar os elementos na tela. Widget por sua vez é tudo que pode ser inserido numa janela.

3. Serve para anexar um widget à janela. Sem eles não seríamos capazes de visualizar o elemento. Você pode posicionar elementos na tela passando um parâmetro opcional ao método pack,chamado side, e atribuindo à ele um desses quatro valores: LEFT, RIGHT, TOP ou BOTTOM.

4. O método bind serve para criar eventos relacionados a um determinado widget, como o clicar de um botão e uma tecla.


Com isso concluímos nosso pequeno tutorial. O que você achou? Não seja tímido! Estamos aceitando sugestões de matérias para tutoriais. Sabe aquele assunto interessante mas precisa de alguém para dar um empurrãozinho? Envia pra gente! Vamos adorar sua sugestão. Boa sorte e até a próxima!

Jornal PETNews - Edição: Julie Pessoa- Revisão: Lívia Sampaio e Gleyser Guimarães
Grupo PET Computação UFCG, 2013. All rights reserved.