Prévia do material em texto
MAB224 – Programação
de Computadores II
Prof. Franklin Marquezino
Universidade Federal do Rio de Janeiro
Parte V
Introdução ao Tkinter
Bibliografia recomendada
● Steve Ferg, “Pensando em Tkinter”
PDF disponível gratuitamente na web
● Consultem sempre, na página do nosso curso,
versões atualizadas destes slides
● Consultem também os slides do curso do Prof.
Claudio Esperança. Há um link na página do
nosso curso.
Interfaces gráficas
● Também chamadas de Graphical User
Interfaces (GUI)
● Usadas em aplicações modernas que
requerem uma interação constante com o
usuário
– Maior usabilidade e naturalidade do que
interfaces textuais
Interfaces gráficas
● Aplicação apresenta uma ou mais janelas com
elementos gráficos que servem para comandar
ações, especificar parâmetros, desenhar e exibir
gráficos, etc.
● Algumas bibliotecas (toolkits) para construção de
interfaces:
– Qt
– Gtk
– wxWindows
– Tk
Interfaces gráficas
● Python permite usar várias bibliotecas de
construção de GUI. Exemplos:
– PyQt → usa Qt
– PyGtk → usa Gtk
– wxPython → usa wxWindows
– Tkinter → usa Tk
● Multiplataforma, ou seja, funciona em
Windows, Linux, Mac, etc.
Usando Tkinter
● Vamos começar por um programa mínimo:
from Tkinter import *
root = Tk()
root.mainloop()
● O que aparece na tela?
Usando Tkinter
● Vamos definir tamanho e título para a
janela:
root.geometry("400x200+100+100")
root.title("Aula de Tkinter")
● Objetos da classe Tk possuem muitos
outros métodos interessantes.
Elementos de interface
● Elementos de interface (widgets)
correspondem a objetos de diversas
classes. Por exemplo:
– Label
– Button
– Entry
– Menu
– Spinbox
– etc.
Criando rótulos
● Por exemplo:
mlabel1 = Label(root,text="Um rótulo qualquer")
mlabel1.pack()
Outras opções de Labels:
definindo a fonte
● Por exemplo:
mlabel1 = Label(root,text="Um rótulo qualquer",
font = (“Times”, 20, “italic”) )
mlabel1.pack()
Outras opções de Labels:
definindo cor
● Por exemplo:
mlabel1 = Label(root,text="Um rótulo qualquer",
fg=”blue”, bg=”white” )
mlabel1.pack()
Outras opções de Labels
● Também funciona:
mlabel1 = Label(root,text="Um rótulo qualquer")
mlabel1.configure(fg=”blue”)
mlabel1.configure(bg=”white”)
mlabel1.configure(font = (“Times”, 20, “italic”) )
mlabel1.pack()
Gerentes de geometria
● Posição e tamanho dos elementos
controlados por gerentes de geometria
– pack
– grid
– place
● Atividade: vamos criar mais labels e testar
todos os gerentes de geometria
Usando pack
mlabel1 = Label(root,text="Um rótulo qualquer")
mlabel1.pack()
mlabel2 = Label(root,text="Um outro rótulo")
mlabel2.pack()
mlabel2 = Label(root,text="Mais um rótulo")
mlabel2.pack()
Opções do pack
mlabel1 = Label(root,text="Um rótulo qualquer")
mlabel1.pack(side=LEFT)
mlabel2 = Label(root,text="Um outro rótulo")
mlabel2.pack(side=LEFT)
mlabel2 = Label(root,text="Mais um rótulo")
mlabel2.pack(side=LEFT)
Usando grid
mlabel1 = Label(root,text="Um rótulo qualquer")
mlabel1.grid(row=0, column=0)
mlabel2 = Label(root,text="Um outro rótulo")
mlabel2.grid(row=1, column=0)
mlabel2 = Label(root,text="Mais um rótulo")
mlabel2.grid(row=1, column=1)
Usando place
mlabel1 = Label(root,text="Um rótulo qualquer")
mlabel1.place(x=50, y=20)
mlabel2 = Label(root,text="Um outro rótulo")
mlabel2.place(x=100, y=60)
mlabel2 = Label(root,text="Mais um rótulo")
mlabel2.place(x=150, y=100)
Criando botões
● Experimentem:
mbutton1 = Button(root,text="OK")
mbutton1.pack()
● O que acontece? O que o botão faz?
Programação com eventos
● Diferente da programação convencional
● O programa não está sob controle 100%
do tempo
– Programa entrega controle ao sistema
– Em Tk: método (função) mainloop
Programação com eventos
● Interação gera eventos
– Acionamento de um menu ou de um
botão
– Mouse arrastado sobre uma janela
– Uma caixa de texto teve seu valor
alterado
● O tratamento de um evento é feito por uma
rotina callback
A opção command
● Voltando ao exemplo do botão: queremos executar uma
função (rotina, método) quando clicarmos!
● Experimentem:
def ok():
mlabel2 = Label(root, text="Você clicou em OK!")
mlabel2.pack()
mbutton1 = Button(root,text="OK", command=ok)
mbutton1.pack()
Exercício
● A partir do exemplo anterior, crie um botão
para sair do programa
● Dica: use o método destroy() da classe Tk
– Exemplo: root.destroy() fecha a janela
Quatro questões básicas
na programação de GUIs
● Como a interface vai se parecer?
● O que a interface vai fazer?
● Como associar o parecer ao fazer?
● Como escrever um código que espera a
interação do usuário?
Jargão básico de
programação de GUIs
● Widgets (elementos de interface): servem para
especificarmos como a interface vai se parecer
● Event handler, callback: o que a interface vai
fazer
● Binding: associação de um event handler a uma
widget. Ou seja, associar o parecer ao fazer.
● Event loop: espera interação do usuário
Contêineres
● Além das widgets visíveis, o Tkinter
também oferece alguns contêineres, como
Frame e Canvas
● Frame é um painel invisível e elástico,
onde você pode colocar outras widgets
● Canvas é uma tela onde você pode
desenhar
Usando o contêiner Canvas
● O Canvas precisa ser associado a um mestre
● Exemplo:
root = Tk()
canvas = Canvas(root, height=400, width=400)
canvas.pack()
● Até aqui, note que não aparece nada.
Usando o contêiner Canvas
● Você pode desenhar em cima do Canvas
● Exemplo:
root = Tk()
canvas = Canvas(root, height=400, width=400)
can.create_line(305,200,400,200)
can.create_oval(100,100,300,300, fill='yellow')
canvas.pack()
Usando o contêiner Frame
● O Frame precisa ser associado a um
mestre
● As widgets são colocadas no Frame
● Exemplo:
root = Tk()
frame = Frame(root)
frame.pack()
Como fica isso no programa?
● Exemplo:
from Tkinter import *
root = Tk()
frame1 = Frame(root)
frame1.pack()
root.mainloop()
E se tiver Label, Button, etc?
● Exemplo:
from Tkinter import *
def ok():
print 'OK'
root = Tk()
frame1 = Frame(root)
frame1.pack()
button_ok = Button(frame1, text='OK', command=ok)
button_ok.pack()
root.mainloop()
O programa está crescendo...
Qual a melhor forma de lidar com isso?
● Nós já aprendemos: CLASSES!
● Por exemplo:
from Tkinter import *
class MyApp:
def __init__(self, master):
self.frame1 = Frame( master )
self.frame1.pack()
self.button_ok = Button(self.frame1, text='OK')
self.button_ok.pack()
root = Tk()
app = MyApp(root)
root.mainloop()
Agora só falta definir o que o botão vai fazer!
● Isso é fácil:
from Tkinter import *
class MyApp:
def __init__(self, master):
self.frame1 = Frame( master )
self.frame1.pack()
self.button_ok = Button(self.frame1, text='OK', command=self.ok)
self.button_ok.pack()
def ok(self):
print 'OK, botao foi pressionado!'
root = Tk()
app = MyApp(root)
root.mainloop()
Criando caixas de entrada
● Experimentem:
entry1 = Entry(root)
entry1.pack()
● O que acontece? Não seria legal poder
usar o valor digitado para alguma coisa?
Usando caixas de entrada
● Experimentem:
def ok():
val = entry1.get()
mlabel2 = Label(root, text="Li o valor %s na caixa" % val)
mlabel2.pack()
Lembram desse tipo de
comando? Trata-se de formatação
de strings! Nesse caso, %s é
substituído pelo conteúdo de val.
Há outras formas de formatar
strings, consulte o site do curso.
O principal desse
exemplo é o método
get da classe Entry!
● Vamos fazer um programa como esse abaixo
– Eu ajudo, mas quero participação!
Exercício
Caixas de diálogo
● No caso de uma exceção, como poderíamos fazer
aparecer uma mensagem de erro?
● Inclua:
from tkMessageBox import *
● Experimente:
except ZeroDivisionError:
mlabel_resdiv.configure(text="erro")
showerror("Erro", "Divisão por zero!")
return
Caixas de diálogo● Além de showerror, temos:
– showinfo()
– showwarning()
● Experimentem!
Caixas de diálogo
● Quando o usuário clicar em “Sair”, vamos
perguntar se ele tem certeza
def sair():
certeza = askyesno("Sair da calculadora",
"Tem certeza que deseja sair?")
if certeza:
mGui.destroy()
Seleção de cor
● No Tkinter também temos caixas de
diálogo específicas para diversas
atividades avançadas. Por exemplo:
from tkColorChooser import *
…
(rgb,hx) = askcolor( )
label.configure(fg=hx)
Outros diálogos simples
● Experimentem também:
from tkSimpleDialog import *
…
x = askstring('Titulo', 'Peça uma string pro usuário')
y = askinteger('Titulo', 'Peça um inteiro pro usuário')
z = askfloat('Titulo', 'Peça um float pro usuário')
Abrindo outras janelas
● Use a widget Toplevel
root = Tk()
…
top = Toplevel()
top.title('Titulo da janela secundaria')
lab = Label(top, text='Testando...')
lab.pack()
…
root.mainloop()
Criando menus
● Vamos criar um menu em cascata
● Vamos usar um processo “de fora para
dentro”
● Começamos com
menubar = Menu(root)
root.configure(menu=menubar)
● Mas só isso ainda não faz nada.
Precisamos acrescentar os ítens do menu.
Criando menus
● A partir dos comandos anteriores, acrescente mais um
nível:
menubar = Menu(root)
arqmenu = Menu(menubar)
menubar.add_cascade(label="Arquivo",menu=arqmenu)
ajumenu = Menu(menubar)
menubar.add_cascade(label="Ajuda",menu=ajumenu)
root.config(menu=menubar)
Criando menus
● A partir dos comandos anteriores, crie mais um nível:
arqmenu = Menu(menubar)
menubar.add_cascade(label="Arquivo",menu=arqmenu)
arqmenu.add_command(label="Abrir")
arqmenu.add_command(label="Salvar")
arqmenu.add_command(label="Sair")
● Esse menu ainda não faz nada. Tem que colocar
comandos!
Criando menus
● Experimentem:
arqmenu = Menu(menubar, tearoff=0)
arqmenu.add_command(label="Abrir",command=self.abrir)
arqmenu.add_command(label="Salvar",command=self.save)
arqmenu.add_command(label="Sair",command=self.sair)
menubar.add_cascade(label="Arquivo", menu=arqmenu)
● Notaram alguma diferença com tearoff=0? Olhem bem!
● Exercício: acrescentem mais menus!
Parecido com o
que fazíamos
com Button
Mais eventos
● É possível tratar muitos eventos
interessantes, além de cliques em botões e
menus!
● Por exemplo, posso fazer algo quando
uma label for clicada com o botão direito,
ou quando der dois cliques numa parte da
tela, etc!
● Pra isso usamos o método bind
Mais eventos
● Experimentem:
def ajuda_num(self, evento):
showinfo("Ajuda", "Parte de cima da fração.")
return
mlabel_num.bind("", self.ajuda_num)
Precisa de argumento
na função callback,
mesmo que não
seja usado
Mais eventos
● Experimentem:
def ajuda_num(self, evento = None):
showinfo("Ajuda", "Parte de cima da fração.")
return
mlabel_num.bind("", self.ajuda_num)
É sempre bom colocar None
como default
Outros eventos
● Testem também os seguintes eventos:
–
–
–
–
–
● Eventos do teclado (associem à janela principal):
– , , , , etc
– , , etc
– , , etc
Veja também...
● Slides do curso de Python do Cláudio Esperança,
da UFRJ: http://orion.lcg.ufrj.br/python/
● Se não tiverem problemas com inglês, podem
olhar aqui também: http://zetcode.com/gui/tkinter/
(Está num nível um pouco mais avançado.
Podem olhar os exemplos, mas não se
preocupem com os detalhes. Podem tirar as
dúvidas comigo na aula.)
Slide 1
Slide 2
Slide 3
Slide 4
Slide 5
Slide 6
Slide 7
Slide 8
Slide 9
Slide 10
Slide 11
Slide 12
Slide 13
Slide 14
Slide 15
Slide 16
Slide 17
Slide 18
Slide 19
Slide 20
Slide 21
Slide 22
Slide 23
Slide 24
Slide 25
Slide 26
Slide 27
Slide 28
Slide 29
Slide 30
Slide 31
Slide 32
Slide 33
Slide 34
Slide 35
Slide 36
Slide 37
Slide 38
Slide 39
Slide 40
Slide 41
Slide 43
Slide 44
Slide 45
Slide 46
Slide 47
Slide 48
Slide 49
Slide 50
Slide 51
Slide 52