Curso
Antes de começar, é importante que você já conheça Python para aprender Tkinter. Se você é novo em Python, confira o curso Introduction to Python da DataCamp e nosso guia de como aprender Python.
Introdução
Muita gente escreve código e o executa no terminal ou em uma IDE (Ambiente de Desenvolvimento Integrado), e o código gera um resultado conforme o esperado, seja no terminal ou na própria IDE. Mas e quando você quer que seu sistema tenha uma interface mais amigável e bonita, ou quando sua aplicação exige uma GUI?
GUI nada mais é do que um app de desktop que oferece uma interface para você interagir com o computador e melhora a experiência de enviar comandos (entrada via linha de comando) para seu código. Elas são usadas para realizar diferentes tarefas em desktops, notebooks e outros dispositivos eletrônicos.
Algumas aplicações que usam o poder de uma GUI:
- Criação de uma calculadora com interface e funcionalidades típicas.
- Editores de texto e IDEs para programar são apps com GUI.
- Sudoku, xadrez, paciência etc. são jogos que você joga em apps com GUI.
- Chrome, Firefox, Microsoft Edge e outros navegadores são apps com GUI.
Outro caso de uso interessante: uma GUI para controlar um drone pelo seu laptop, com botões para manobrar o drone e uma tela exibindo, em tempo real, o vídeo da câmera capturado pelo drone.
Veja alguns frameworks que o Python oferece para desenvolver GUIs:
- PyQT é um dos bindings cross-platform mais populares de Python para a biblioteca Qt, parte do framework de desenvolvimento de aplicativos Qt. O Qt pertence principalmente à Nokia. Atualmente, o PyQT está disponível para praticamente todos os sistemas operacionais como Unix/Linux, Windows e Mac OS X. Ele une o melhor de Python e Qt e dá flexibilidade para você decidir entre escrever tudo em Python puro ou usar o Qt Designer para criar diálogos visuais.
- Kivy é voltado para a criação de novas interfaces de usuário e é um framework acelerado por OpenGL ES 2. Assim como o PyQt, o Kivy também suporta quase todas as plataformas: Windows, MacOSX, Linux, Android e iOS. É open source e vem com mais de 20 widgets prontos na sua toolkit.
- Jython é um port de Python para Java, que dá aos scripts Python acesso transparente às bibliotecas de classes Java na máquina local.
- WxPython, anteriormente conhecido como WxWindows (hoje biblioteca WxWidgets), é um wrapper de alto nível, open source, para uma biblioteca de GUI multiplataforma. É implementado como um módulo de extensão Python. Com WxPython, você pode criar aplicativos nativos para Windows, Mac OS e Unix.
- PyGUI é um framework gráfico multiplataforma para Unix, Macintosh e Windows. Em comparação com outros frameworks de GUI, o PyGUI é de longe o mais simples e leve, pois a API está totalmente alinhada com Python. O PyGUI insere pouquíssimo código entre a plataforma de GUI e a aplicação Python; por isso, a interface geralmente fica com a aparência nativa do sistema.
E, por fim, o framework que é o tema do tutorial de hoje: Tkinter!
- Tkinter normalmente vem empacotado com o Python, utiliza o Tk e é o framework padrão de GUI do Python. É famoso pela simplicidade e pela interface gráfica intuitiva. É open source e está disponível sob a Python License.
Observação: Tkinter já vem pré-instalado com o Python 3, então você não precisa se preocupar em instalar.
Agora, vamos construir uma GUI bem simples com Tkinter e entender o processo com a ajuda de um diagrama de fluxo.
Vamos dissecar o diagrama acima e entender o papel de cada componente:
- Primeiro, importe o componente principal, ou seja, o módulo
Tkinter. - Em seguida, inicialize o gerenciador da janela com o método
tkinter.Tk()e atribua-o a uma variável. Esse método cria uma janela em branco com os botões de fechar, maximizar e minimizar, como qualquer GUI comum. - Opcionalmente, você pode
renomearo título da janela como preferir comwindow.title(title_of_the_window). - Depois, use um
widgetchamadoLabel, que insere um texto na janela. - Use o gerenciador de
geometriado Tkinter chamadopack()para exibir o widget com o tamanho necessário. - Por fim, use o método
mainloop()para manter a janela exibida até que você a feche manualmente. Ele executa um loop infinito em segundo plano.
import tkinter
window = tkinter.Tk()
# to rename the title of the window
window.title("GUI")
# pack is used to show the object in the window
label = tkinter.Label(window, text = "Welcome to DataCamp's Tutorial on Tkinter!").pack()
window.mainloop()
Após executar o código acima no terminal, você verá um resultado semelhante ao mostrado abaixo.

Da mesma forma, você pode usar o widget Button, e a GUI exibirá um botão em vez de texto (Label).
import tkinter
window = tkinter.Tk()
window.title("Button GUI")
button_widget = tkinter.Button(window,text="Welcome to DataCamp's Tutorial on Tkinter")
button_widget.pack()
tkinter.mainloop()

Você já viu como usar widgets no Tkinter, mas vamos conferir quais outros widgets estão disponíveis e como cada um funciona.
Domine suas habilidades em dados com o DataCamp
Mais de 10 milhões de pessoas aprendem Python, R, SQL e outras habilidades tecnológicas usando nossos cursos práticos elaborados por especialistas do setor.

Widgets
Widgets são como os elementos em HTML. No Tkinter, você encontra diferentes tipos de widgets para diferentes tipos de elementos. Eles são componentes padrão de GUI e oferecem controles como botões, textos, menus e caixas de texto.
Vamos entender esses widgets no Tkinter com um exemplo (Fonte).
-
Button: o widget Button tem a propriedade liga/desliga. Quando o usuário clica no botão, um evento é disparado no Tkinter.
Sintaxe: button_widget = tk.Button(widget, option=placeholder), onde
widgeté o argumento para a janela/quadro pai eoptioné um placeholder que pode receber diversos valores, como cor de fundo e de texto, fonte, command (para chamar função), imagem, altura e largura do botão. -
Canvas: o Canvas é usado para desenhar formas na sua GUI e oferece vários métodos de desenho.
Sintaxe: canvas_widget = tk.Canvas(widget, option=placeholder), onde
widgeté o parâmetro para a janela/quadro pai eoptionpode receber valores como largura da borda, cor de fundo, altura e largura do widget. -
Checkbutton: o Checkbutton registra estados ligado/desligado ou verdadeiro/falso. Ele permite selecionar mais de uma opção ao mesmo tempo, e também deixar desmarcado.
Sintaxe: checkbutton_widget = tk.CheckButton(widget, option=placeholder), onde
widgeté o parâmetro para a janela/quadro pai eoptionpode receber valores como título, texto, cores de fundo e de texto quando o cursor está sobre o widget, fonte, imagem etc. -
Entry: o widget Entry cria campos de entrada para capturar texto do usuário dentro da GUI.
Sintaxe: entry_widget = tk.Entry(widget, option=placeholder), onde
widgeté o parâmetro para a janela/quadro pai eoptionpode receber valores como largura da borda, cor de fundo, largura e altura do botão etc. -
Frame: o Frame é usado como contêiner no Tkinter para agrupar e organizar widgets adequadamente.
Sintaxe: frame_widget = tk.Frame(widget, option=placeholder), onde
widgeté o parâmetro para a janela/quadro pai eoptionpode receber valores como largura da borda, altura e largura do widget, highlightcolor (cor quando o widget está em foco). -
Label: o Label cria widgets de linha única como texto, imagens etc.
Sintaxe: label_widget = tk.Label(widget, option=placeholder), onde
widgeté o parâmetro para a janela/quadro pai eoptionpode receber valores como fonte, cor de fundo, imagem, largura e altura do botão.
Você encontra a lista completa de widgets na documentação oficial do Python.
Gerenciamento de geometria
Todos os widgets no Tkinter têm medidas de geometria. Essas medidas permitem organizar os widgets nas áreas do quadro pai ou do widget pai.
Uma das classes de gerenciamento de geometria, o pack(), já foi abordada aqui.
Para isso, o Tkinter oferece três gerenciadores de geometria principais:
- pack(): organiza os widgets em blocos, ocupando toda a largura disponível. É um método tradicional para mostrar widgets na janela.
- grid(): organiza os widgets em uma estrutura em forma de tabela. Você vai ver em detalhes mais adiante neste tutorial.
- place(): posiciona os widgets em um ponto específico indicado pelo usuário dentro do widget pai.
Organizando layout e widgets
Nesta parte do tutorial, você vai usar geometry e widgets juntos para ver a mágica do Tkinter.
Para organizar o layout na window, use a classe de widget Frame. Vamos criar um programa simples para ver como o Frame funciona.
-
Você vai definir dois frames — superior e inferior — com a ajuda da classe
pack. A classe Frame ajuda a criar uma divisão na janela. Basicamente, a janela única é replicada duas vezes como topo e base em forma de Frames. -
Por fim, você criará quatro botões na janela, dois para cada frame. Você pode nomear e colorir os botões como preferir, passando parâmetros.
import tkinter
# Let's create the Tkinter window.
window = tkinter.Tk()
window.title("GUI")
# You will first create a division with the help of Frame class and align them on TOP and BOTTOM with pack() method.
top_frame = tkinter.Frame(window).pack()
bottom_frame = tkinter.Frame(window).pack(side = "bottom")
# Once the frames are created then you are all set to add widgets in both the frames.
btn1 = tkinter.Button(top_frame, text = "Button1", fg = "red").pack() #'fg or foreground' is for coloring the contents (buttons)
btn2 = tkinter.Button(top_frame, text = "Button2", fg = "green").pack()
btn3 = tkinter.Button(bottom_frame, text = "Button3", fg = "purple").pack(side = "left") #'side' is used to left or right align the widgets
btn4 = tkinter.Button(bottom_frame, text = "Button4", fg = "orange").pack(side = "left")
window.mainloop()
Vamos executar o código acima e ver o resultado.

Grid
Assim como um Frame, o grid é outra forma de organizar os widgets. Ele usa o conceito de matriz linha-coluna. Vamos traçar uma analogia entre a classe grid e a ideia de linhas e colunas com a ajuda do diagrama abaixo.

O grid recebe principalmente dois parâmetros: row e column. Como mostrado na figura, imagine que 00 corresponde ao primeiro botão, enquanto 01 ao segundo. Para posicionar dois botões lado a lado, grid usará os parâmetros row e column como 00 e 01, respectivamente.
Vamos usar checkbutton para entender como a classe grid funciona. Você vai definir dois checkbuttons e especificar um texto para cada um. O estado dos botões será definido por onvalue e offvalue, enquanto o estado atual será acompanhado por IntVar(), armazenado em uma variável. Quando offvalue=1 e onvalue=0, o checkbutton correspondente ficará marcado.
Agora, sobre a classe grid, você passará o parâmetro row, que posiciona o botão na primeira linha se row=0 e na segunda se row=1.
import tkinter
from tkinter import *
top = tkinter.Tk()
CheckVar1 = IntVar()
CheckVar2 = IntVar()
tkinter.Checkbutton(top, text = "Machine Learning",variable = CheckVar1,onvalue = 1, offvalue=0).grid(row=0,sticky=W)
tkinter.Checkbutton(top, text = "Deep Learning", variable = CheckVar2, onvalue = 0, offvalue =1).grid(row=1,sticky=W)
top.mainloop()
Vamos executar este código e ver o resultado.

Vamos a outro exemplo para entender o grid. Neste caso, você também passará column como parâmetro junto com row.
import tkinter
# Let's create the Tkinter window
window = tkinter.Tk()
window.title("GUI")
# You will create two text labels namely 'username' and 'password' and and two input labels for them
tkinter.Label(window, text = "Username").grid(row = 0) #'username' is placed on position 00 (row - 0 and column - 0)
# 'Entry' class is used to display the input-field for 'username' text label
tkinter.Entry(window).grid(row = 0, column = 1) # first input-field is placed on position 01 (row - 0 and column - 1)
tkinter.Label(window, text = "Password").grid(row = 1) #'password' is placed on position 10 (row - 1 and column - 0)
tkinter.Entry(window).grid(row = 1, column = 1) #second input-field is placed on position 11 (row - 1 and column - 1)
# 'Checkbutton' class is for creating a checkbutton which will take a 'columnspan' of width two (covers two columns)
tkinter.Checkbutton(window, text = "Keep Me Logged In").grid(columnspan = 2)
window.mainloop()
Veja a saída do código acima:

Demais, né? Super simples e muito parecido com o que faríamos em HTML.
Funções de binding ou command
Funções de binding ou command são chamadas sempre que um evento ocorre ou é acionado.
Vamos ver um exemplo para entender as funções de binding.
Você vai definir um botão que, ao ser clicado, chama a função DataCamp_Tutorial. Essa função criará um novo label com o texto GUI with Tkinter!.
import tkinter
# Let's create the Tkinter window
window = tkinter.Tk()
window.title("GUI")
# creating a function called DataCamp_Tutorial()
def DataCamp_Tutorial():
tkinter.Label(window, text = "GUI with Tkinter!").pack()
tkinter.Button(window, text = "Click Me!", command = DataCamp_Tutorial).pack()
window.mainloop()
Execute o código e observe a saída.

Além de acionar funções de binding com cliques do mouse, eventos podem ser disparados por movimento do mouse, mouse-over, cliques, rolagem etc.
Agora vamos conhecer a função bind, que oferece a mesma funcionalidade.
Evento de clique do mouse via método bind
O método bind oferece uma forma bem simples de implementar eventos de clique do mouse. Veja três funções predefinidas que podem ser usadas direto com bind.
Eventos de clique são de três tipos: leftClick, middleClick e rightClick.
- O parâmetro
<Button-1>do método bind é o evento de clique com o botão esquerdo; ou seja, ao clicar o botão esquerdo, o bind chamará a função especificada como segundo parâmetro. <Button-2>para o clique do meio<Button-3>para o clique direito
Agora, você vai aprender a chamar uma função específica com base no evento que ocorrer.
- Execute o programa a seguir e clique com os botões esquerdo, do meio e direito para chamar a função correspondente.
- Essa função criará um novo label com o texto especificado.
import tkinter
# Let's create the Tkinter window
window = tkinter.Tk()
window.title("GUI")
#You will create three different functions for three different events
def left_click(event):
tkinter.Label(window, text = "Left Click!").pack()
def middle_click(event):
tkinter.Label(window, text = "Middle Click!").pack()
def right_click(event):
tkinter.Label(window, text = "Right Click!").pack()
window.bind("<Button-1>", left_click)
window.bind("<Button-2>", middle_click)
window.bind("<Button-3>", right_click)
window.mainloop()
Vamos executar o código acima.

Caixas de alerta
Você pode criar caixas de alerta no Tkinter usando o método messagebox. Também dá para criar perguntas usando messagebox.
Aqui vamos criar uma caixa de alerta simples e também uma pergunta. Para gerar um alerta, você usará a função showinfo de messagebox. Para criar uma pergunta, use o método askquestion e, com base na resposta, mostre um Label na GUI.
import tkinter
import tkinter.messagebox
# Let's create the Tkinter window
window = tkinter.Tk()
window.title("GUI")
# Let's create a alert box with 'messagebox' function
tkinter.messagebox.showinfo("Alert Message", "This is just a alert message!")
# Let's also create a question for the user and based upon the response [Yes or No Question] display a message.
response = tkinter.messagebox.askquestion("Tricky Question", "Do you love Deep Learning?")
# A basic 'if/else' block where if user clicks on 'Yes' then it returns 1 else it returns 0. For each response you will display a message with the help of 'Label' method.
if response == 1:
tkinter.Label(window, text = "Yes, offcourse I love Deep Learning!").pack()
else:
tkinter.Label(window, text = "No, I don't love Deep Learning!").pack()
window.mainloop()
Vamos rodar rapidamente o código acima e ver o resultado.


Renderizando imagens
Se você acompanhou até aqui, adicionar imagens e ícones na GUI vai ser moleza. Basta usar o método PhotoImage do Tkinter e passar o file_path como parâmetro.
Sem mais delongas, vamos escrever um código para exibir uma imagem na GUI.
import tkinter
# Let's create the Tkinter window
window = tkinter.Tk()
window.title("GUI")
# In order to display the image in a GUI, you will use the 'PhotoImage' method of Tkinter. It will an image from the directory (specified path) and store the image in a variable.
icon = tkinter.PhotoImage(file = "CNN.png")
# Finally, to display the image you will make use of the 'Label' method and pass the 'image' variriable as a parameter and use the pack() method to display inside the GUI.
label = tkinter.Label(window, image = icon)
label.pack()
window.mainloop()

Parabéns por chegar até aqui!
Como bônus, você vai criar uma Calculator usando tudo o que aprendeu até agora. Vamos encerrar este tutorial em grande estilo.
Criando uma calculadora com Tkinter
Todo app com GUI envolve duas etapas:
- Criar a interface do usuário
- Adicionar funcionalidades à GUI
Vamos começar a criar a calculadora. A maior parte do código é autoexplicativa, e algumas linhas têm comentários com explicações.
from tkinter import *
# Let's create the Tkinter window
window = Tk()
# Then, you will define the size of the window in width(312) and height(324) using the 'geometry' method
window.geometry("312x324")
# In order to prevent the window from getting resized you will call 'resizable' method on the window
window.resizable(0, 0)
#Finally, define the title of the window
window.title("Calcualtor")
# Let's now define the required functions for the Calculator to function properly.
# 1. First is the button click 'btn_click' function which will continuously update the input field whenever a number is entered or any button is pressed it will act as a button click update.
def btn_click(item):
global expression
expression = expression + str(item)
input_text.set(expression)
# 2. Second is the button clear 'btn_clear' function clears the input field or previous calculations using the button "C"
def btn_clear():
global expression
expression = ""
input_text.set("")
# 3. Third and the final function is button equal ("=") 'btn_equal' function which will calculate the expression present in input field. For example: User clicks button 2, + and 3 then clicks "=" will result in an output 5.
def btn_equal():
global expression
result = str(eval(expression)) # 'eval' function is used for evaluating the string expressions directly
# you can also implement your own function to evalute the expression istead of 'eval' function
input_text.set(result)
expression = ""
expression = ""
# In order to get the instance of the input field 'StringVar()' is used
input_text = StringVar()
# Once all the functions are defined then comes the main section where you will start defining the structure of the calculator inside the GUI.
# The first thing is to create a frame for the input field
input_frame = Frame(window, width = 312, height = 50, bd = 0, highlightbackground = "black", highlightcolor = "black", highlightthickness = 1)
input_frame.pack(side = TOP)
# Then you will create an input field inside the 'Frame' that was created in the previous step. Here the digits or the output will be displayed as 'right' aligned
input_field = Entry(input_frame, font = ('arial', 18, 'bold'), textvariable = input_text, width = 50, bg = "#eee", bd = 0, justify = RIGHT)
input_field.grid(row = 0, column = 0)
input_field.pack(ipady = 10) # 'ipady' is an internal padding to increase the height of input field
# Once you have the input field defined then you need a separate frame which will incorporate all the buttons inside it below the 'input field'
btns_frame = Frame(window, width = 312, height = 272.5, bg = "grey")
btns_frame.pack()
# The first row will comprise of the buttons 'Clear (C)' and 'Divide (/)'
clear = Button(btns_frame, text = "C", fg = "black", width = 32, height = 3, bd = 0, bg = "#eee", cursor = "hand2", command = lambda: btn_clear()).grid(row = 0, column = 0, columnspan = 3, padx = 1, pady = 1)
divide = Button(btns_frame, text = "", fg = "black", width = 10, height = 3, bd = 0, bg = "#eee", cursor = "hand2", command = lambda: btn_click("")).grid(row = 0, column = 3, padx = 1, pady = 1)
# The second row will comprise of the buttons '7', '8', '9' and 'Multiply (*)'
seven = Button(btns_frame, text = "7", fg = "black", width = 10, height = 3, bd = 0, bg = "#fff", cursor = "hand2", command = lambda: btn_click(7)).grid(row = 1, column = 0, padx = 1, pady = 1)
eight = Button(btns_frame, text = "8", fg = "black", width = 10, height = 3, bd = 0, bg = "#fff", cursor = "hand2", command = lambda: btn_click(8)).grid(row = 1, column = 1, padx = 1, pady = 1)
nine = Button(btns_frame, text = "9", fg = "black", width = 10, height = 3, bd = 0, bg = "#fff", cursor = "hand2", command = lambda: btn_click(9)).grid(row = 1, column = 2, padx = 1, pady = 1)
multiply = Button(btns_frame, text = "*", fg = "black", width = 10, height = 3, bd = 0, bg = "#eee", cursor = "hand2", command = lambda: btn_click("*")).grid(row = 1, column = 3, padx = 1, pady = 1)
# The third row will comprise of the buttons '4', '5', '6' and 'Subtract (-)'
four = Button(btns_frame, text = "4", fg = "black", width = 10, height = 3, bd = 0, bg = "#fff", cursor = "hand2", command = lambda: btn_click(4)).grid(row = 2, column = 0, padx = 1, pady = 1)
five = Button(btns_frame, text = "5", fg = "black", width = 10, height = 3, bd = 0, bg = "#fff", cursor = "hand2", command = lambda: btn_click(5)).grid(row = 2, column = 1, padx = 1, pady = 1)
six = Button(btns_frame, text = "6", fg = "black", width = 10, height = 3, bd = 0, bg = "#fff", cursor = "hand2", command = lambda: btn_click(6)).grid(row = 2, column = 2, padx = 1, pady = 1)
minus = Button(btns_frame, text = "-", fg = "black", width = 10, height = 3, bd = 0, bg = "#eee", cursor = "hand2", command = lambda: btn_click("-")).grid(row = 2, column = 3, padx = 1, pady = 1)
# The fourth row will comprise of the buttons '1', '2', '3' and 'Addition (+)'
one = Button(btns_frame, text = "1", fg = "black", width = 10, height = 3, bd = 0, bg = "#fff", cursor = "hand2", command = lambda: btn_click(1)).grid(row = 3, column = 0, padx = 1, pady = 1)
two = Button(btns_frame, text = "2", fg = "black", width = 10, height = 3, bd = 0, bg = "#fff", cursor = "hand2", command = lambda: btn_click(2)).grid(row = 3, column = 1, padx = 1, pady = 1)
three = Button(btns_frame, text = "3", fg = "black", width = 10, height = 3, bd = 0, bg = "#fff", cursor = "hand2", command = lambda: btn_click(3)).grid(row = 3, column = 2, padx = 1, pady = 1)
plus = Button(btns_frame, text = "+", fg = "black", width = 10, height = 3, bd = 0, bg = "#eee", cursor = "hand2", command = lambda: btn_click("+")).grid(row = 3, column = 3, padx = 1, pady = 1)
# Finally, the fifth row will comprise of the buttons '0', 'Decimal (.)', and 'Equal To (=)'
zero = Button(btns_frame, text = "0", fg = "black", width = 21, height = 3, bd = 0, bg = "#fff", cursor = "hand2", command = lambda: btn_click(0)).grid(row = 4, column = 0, columnspan = 2, padx = 1, pady = 1)
point = Button(btns_frame, text = ".", fg = "black", width = 10, height = 3, bd = 0, bg = "#eee", cursor = "hand2", command = lambda: btn_click(".")).grid(row = 4, column = 2, padx = 1, pady = 1)
equals = Button(btns_frame, text = "=", fg = "black", width = 10, height = 3, bd = 0, bg = "#eee", cursor = "hand2", command = lambda: btn_equal()).grid(row = 4, column = 3, padx = 1, pady = 1)
window.mainloop()

Conclusão
Parabéns por finalizar este tutorial!
Com o que você aprendeu aqui, já dá para criar apps simples com GUI. Continue explorando mais métodos de estilização e interação com os objetos em uma GUI.
Um exercício útil é desenvolver aplicações como a calculadora, o que vai aumentar sua confiança e dar uma visão mais completa do que é possível fazer com Tkinter.
Ainda há muito o que explorar, e você talvez queira estudar o conceito de Classes no Tkinter — consulte esta documentação.
Fique à vontade para deixar suas dúvidas sobre o tutorial na seção de comentários abaixo.
