Baixe o app para aproveitar ainda mais
Prévia do material em texto
Roteiro da Aula 02 GUI (continuação) Referência on-line em http://effbot.org/tkinterbook/tkinter-index.htm#class-reference Aplicação: prog1.py Essa aplicação faz uso de Entry Widgets e = Entry(width=10) e.pack(side=LEFT) Como obter o conteúdo de uma Entry Widget? Você pode usar o método get(). imprime(e.get()) O código completo from Tkinter import * def imprime(str): text.config(state=NORMAL) text.insert(END, str + '\n') text.config(state=DISABLED) # trata o clique no botão def clicouBotao(): imprime("Olá %s!" % e.get()) # coloca o Text Widget text = Text(state=DISABLED, width=40) text.pack() # coloca um Label Widget Label(text="Nome: ").pack(side=LEFT, padx=10) # coloca um Entry Widget e = Entry(width=10) e.pack(side=LEFT) # coloca um Button Widget Button(text="Cumprimenta", command=clicouBotao).\ pack(side=LEFT, padx=10) mainloop() Aplicação: prog2.py Vamos modificar o programa anterior de modo que agora o usuário obtenha um cumprimento clicando sobre o botão ou pressionando a tecla Enter, logo após ter digitado seu nome na caixa de texto. De maneira análoga ao que fizemos quando queríamos capturar cliques de mouse no canvas, é possível associar um event handler diretamente a uma Entry Widget entry = Entry(width=10) entry.pack(side=LEFT) # associa um evento ao Entry Widget entry.bind("<Return>", apertouEnter) O código completo from Tkinter import * def imprime(str): text.config(state=NORMAL) text.insert(END, str + '\n') text.config(state=DISABLED) # trata o clique no botão def clicouBotao(): imprime("Olá %s!" % entry.get()) # trata a tecla Enter. Observe que aqui # o parâmetro com o evento é obrigatório def apertouEnter(evento): imprime("Olá %s\n!" % entry.get()) # coloca o Text Widget text = Text(state=DISABLED, width=40) text.pack() # coloca um Label Widget Label(text="Nome: ").pack(side=LEFT, padx=10) # coloca um Entry Widget entry = Entry(width=10) entry.pack(side=LEFT) # coloca um Button Widget Button(text="Cumprimenta", command=clicouBotao).\ pack(side=LEFT, padx=10) # associa um evento ao Entry Widget entry.bind("<Return>", apertouEnter) mainloop() É possível evitar a duplicação de código nas funções clicouBotao() e apertouEnter(), usando uma única função de callback para os dois widgets. from Tkinter import * def imprime(str): text.config(state=NORMAL) text.insert(END, str + '\n') text.config(state=DISABLED) # trata a tecla Enter e o clique no mouse def cumprimenta(evento): imprime("Olá %s!" % entry.get()) # coloca o Text Widget text = Text(state=DISABLED, width=40) text.pack() # coloca um Label Widget Label(text="Nome: ").pack(side=LEFT, padx=10) # coloca um Entry Widget entry = Entry(width=10) entry.pack(side=LEFT) # coloca um Button Widget btn = Button(text="Cumprimenta") btn.pack(side=LEFT, padx=10) entry.bind("<Return>", cumprimenta) btn.bind("<Button-1>", cumprimenta) mainloop() É possível ainda descobrir o widget que gerou o evento através da propriedade widget do evento recebido como parâmetro. from Tkinter import * def imprime(str): text.config(state=NORMAL) text.insert(END, str + '\n') text.config(state=DISABLED) # trata a tecla Enter e o clique no mouse def cumprimenta(evento): if evento.widget == entry: imprime("Olá %s (by entry)!" % entry.get()) else: imprime("Olá %s (by button)!" % entry.get()) # coloca o Text Widget text = Text(state=DISABLED, width=40) text.pack() # coloca um Label Widget Label(text="Nome: ").pack(side=LEFT, padx=10) # coloca um Entry Widget entry = Entry(width=10) entry.pack(side=LEFT) # coloca um Button Widget btn = Button(text="Cumprimenta") btn.pack(side=LEFT, padx=10) # associa o mesmo método de callback a ambos widgets entry.bind("<Return>", cumprimenta) btn.bind("<Button-1>", cumprimenta) mainloop() Outro Gerenciador de Layout, o Grid O gerenciador de layout Grid dispõe os widgets em uma tabela em duas dimensões. O root frame é dividido em linhas e colunas e cada célula na tabela resultante pode acomodar um único widget. Exemplo: from Tkinter import * Button(text="Botão 1").grid(row=0, column=0, padx=5, pady=5) Button(text="Botão 2").grid(row=0, column=1, padx=5, pady=5) Button(text="Botão 3").grid(row=1, column=0, padx=5, pady=5) Button(text="Botão 4").grid(row=1, column=1, padx=5, pady=5) Button(text="Botão 5").grid(row=2, column=0, padx=5, pady=5) Button(text="Botão 6").grid(row=2, column=1, padx=5, pady=5) mainloop() Referência grid(**options) [#] Place the widget in a grid as described by the options. **options Geometry options. column= Insert the widget at this column. Column numbers start with 0. If omitted, defaults to 0. columnspan= If given, indicates that the widget cell should span multiple columns. The default is 1. padx= Optional horizontal padding to place around the widget in a cell. Default is 0. pady= Optional vertical padding to place around the widget in a cell. Default is 0. row= Insert the widget at this row. Row numbers start with 0. If omitted, defaults to the first empty row in the grid. rowspan= If given, indicates that the widget cell should span multiple rows. Default is 1. sticky= Defines how to expand the widget if the resulting cell is larger than the widget itself. This can be any combination of the constants S, N, E, and W, or NW, NE, SW, and SE. For example, W (west) means that the widget should be aligned to the left cell border. W+E means that the widget should be stretched horizontally to fill the whole cell. W+E+N+S means that the widget should be expanded in both directions. Default is to center the widget in the cell. Grid é uma interface, todos os widgets Tkinter implementam todos os métodos dessa interface. É possível fazer com que as células cresçam para acomodar o redimensionamento do frame por parte do usuário. É possível ainda fazer com que os widgets nas células cresçam para ocupar todo o espaço da célula. Exemplo: # esse programa estica os botoes para # ocupar todo o espaço disponível from Tkinter import * # configura o grid para expandir junto com o frame # root é uma referência para o frame master root = Tk() root.grid_columnconfigure(0, weight=1) root.grid_columnconfigure(1, weight=1) root.grid_rowconfigure(0, weight=1) root.grid_rowconfigure(1, weight=1) root.grid_rowconfigure(2, weight=1) # configura os botões para crescerem junto com as células Button(text="Botão 1").grid(row=0, column=0, padx=5, pady=5, sticky=N+S+E+W) Button(text="Botão 2").grid(row=0, column=1, padx=5, pady=5, sticky=N+S+E+W) Button(text="Botão 3").grid(row=1, column=0, padx=5, pady=5, sticky=N+S+E+W) Button(text="Botão 4").grid(row=1, column=1, padx=5, pady=5, sticky=N+S+E+W) Button(text="Botão 5").grid(row=2, column=0, padx=5, pady=5, sticky=N+S+E+W) Button(text="Botão 6").grid(row=2, column=1, padx=5, pady=5, sticky=N+S+E+W) mainloop() Referência grid_columnconfigure(index, **options) [#] Set options for a cell column. To change this for a given widget, you have to call this method on the widget’s parent. index Column index. **options Column options. minsize= Defines the minimum size for the column. Note that if a column is completely empty, it will not be displayed, even if this option is set. pad=Padding to add to the size of the largest widget in the column when setting the size of the whole column. weight= A relative weight used to distribute additional space between columns. A column with the weight 2 will grow twice as fast as a column with weight 1. The default is 0, which means that the column will not grow at all. grid_rowconfigure(index, **options) [#] Set options for a row of cells. To change this for a given widget, you have to call this method on the widget’s parent. index Row index. **options Row options. minsize= Defines the minimum size for the row. Note that if a row is completely empty, it will not be displayed, even if this option is set. pad= Padding to add to the size of the largest widget in the row when setting the size of the whole row. weight= A relative weight used to distribute additional space between rows. A row with the weight 2 will grow twice as fast as a row with weight 1. The default is 0, which means that the row will not grow at all. No entanto, se você achar conveniente, é possível impedir que o usuário redimensione o form principal # impede o usuário de redimensionar o frame principal from Tkinter import * root = Tk() root.resizable(width=False, height=False) Button(text="Botão 1").grid(row=0, column=0) Button(text="Botão 2").grid(row=0, column=1) Button(text="Botão 3").grid(row=1, column=0) Button(text="Botão 4").grid(row=1, column=1) Button(text="Botão 5").grid(row=2, column=0) Button(text="Botão 6").grid(row=2, column=1) mainloop() Desafio: Usando unicamente o Grid como gerenciador de layout, tente produzir o form na figura abaixo. Todos os widget visíveis, são instâncias de Label. Figura 1 - Configuração inicial do frame Figura 2 - Frame após algum redimensionamento Figura 3 - O frame após mais algum redimensionamento Solução: Estude com atenção o código a seguir. Esteja certo de entender todos os detalhes. from Tkinter import * ARIAL = ('Arial', 16) root = Tk() root.config(bg='black') root.grid_rowconfigure(0, weight=1) root.grid_columnconfigure(4, weight=1) Label(text="red", fg='white', bg='red', height=20).\ grid(row=0, column=0, sticky=N+S) Label(text="green", fg='black', bg='green').\ grid(row=0, column=1, sticky=N+S) Label(text="blue", fg='white', bg='blue').\ grid(row=0, column=2, sticky=N+S) Label(text="yellow", fg='black', bg='yellow').\ grid(row=0, column=3, sticky=N+S) Label(text="gravity is center", fg='black', bg='cyan', font=ARIAL, anchor=CENTER, width=40).\ grid(row=1, column=0, columnspan=5, sticky=W+E) Label(text="gravity is right", fg='black', bg='green', font=ARIAL, anchor=E).\ grid(row=2, column=0, columnspan=5, sticky=W+E) Label(text="gravity is left", fg='black', bg='cyan', font=ARIAL, anchor=W).\ grid(row=3, column=0, columnspan=5, sticky=W+E) Label(text="gravity default", fg='black', bg='green', font=ARIAL).\ grid(row=4, column=0, columnspan=5, sticky=W+E) mainloop() Mas, na maioria das vezes, existe sempre outra maneira de fazer as coisas... from Tkinter import * ARIAL = ('Arial', 16) root = Tk() root.config(bg='black') root.grid_rowconfigure(0, weight=1) root.grid_columnconfigure(0, weight=1) # um frame auxiliar. Ocupa a célula (0, 0) do grid original frame=Frame() frame.grid_rowconfigure(0, weight=1) frame.grid(row=0, column=0, sticky=N+S+W) Label(frame, text="red", fg='white', bg='red', height=20).\ grid(row=0, column=0, sticky=N+S) Label(frame, text="green", fg='black', bg='green').\ grid(row=0, column=1, sticky=N+S) Label(frame, text="blue", fg='white', bg='blue').\ grid(row=0, column=2, sticky=N+S) Label(frame, text="yellow", fg='black', bg='yellow').\ grid(row=0, column=3, sticky=N+S) Label(text="gravity is center", fg='black', bg='cyan', font=ARIAL, anchor=CENTER, width=40).\ grid(row=1, column=0, sticky=W+E) Label(text="gravity is right", fg='black', bg='green', font=ARIAL, anchor=E).\ grid(row=2, column=0, sticky=W+E) Label(text="gravity is left", fg='black', bg='cyan', font=ARIAL, anchor=W).\ grid(row=3, column=0, sticky=W+E) Label(text="gravity default", fg='black', bg='green', font=ARIAL).\ grid(row=4, column=0, sticky=W+E) mainloop()
Compartilhar