mab224 – programação de computadores iifranklin/xbt246/04-introducao-tkinter.pdf ·...
Post on 30-Sep-2018
216 Views
Preview:
TRANSCRIPT
MAB224 – Programaçãode Computadores II
Prof. Franklin MarquezinoUniversidade 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ásicasna 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("<Button-3>", 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("<Button-3>", self.ajuda_num)
É sempre bom colocar None como default
Outros eventos● Testem também os seguintes eventos:
– <B1-Motion>
– <ButtonRelease-1>
– <Double-Button-1>
– <Enter>
– <Leave>● Eventos do teclado (associem à janela principal):
– <Return>, <BackSpace>, <Tab>, <Escape>, etc
– <F1>, <F2>, etc
– <Shift-Up>, <Control-Shift-Down>, 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.)
top related