Tkinter permet desenvolupar interfases gràfiques senzilles de forma ràpida. En aquest post faig una senzilla GUI d'exemple. Es tracta d'una pantalla que té dues caixa d'entrada, superior i inferior, i dos botons. En prémer el botó de l'esquerra la informació que hi ha a la caixa superior es mourà a la caixa inferior; i si no hi ha informació a la caixa superior es mostrarà un missatge d'avís. De forma similar, en prémer el botó de la dreta la informació que hi ha la caixa inferior es mourà a la caixa superior; i si no hi ha informació a la caixa inferior es mostrarà un missatge d'avís.
El codi és el següent:
#!/usr/bin/python
# coding: latin-1
#
# http://www.tutorialspoint.com/python/
# http://www.astro.washington.edu/users/rowen/TkinterSummary.html
# http://effbot.org/tkinterbook/
import tkMessageBox
from Tkinter import *
# alternativa
# import Tkinter
# Tkinter.Tk()
class App:
def __init__(self, root):
Label(root, text='Caixa superior').grid(row=1,column=1, ipadx=5, ipady=5, padx=5, pady=5)
self.EntryDalt = Entry(root)
self.EntryDalt.grid(row=1,column=2, ipadx=5, ipady=5, padx=5, pady=5)
Label(root, text='Caixa inferior').grid(row=2,column=1, ipadx=5, ipady=5, padx=5, pady=5)
self.EntryBaix = Entry(root)
self.EntryBaix.grid(row=2,column=2, ipadx=5, ipady=5, padx=5, pady=5)
Label(root, text='---------------').grid(row=3,column=1, columnspan=2, ipadx=5, ipady=5, padx=5, pady=5)
Button1 = Button(root, text="Passa de dalt a baix", command=self.Mostra1)
Button1.grid(row=4,column=1, ipadx=5, ipady=5, padx=5, pady=5)
Button2 = Button(root, text="Passa de baix a dalt", command=self.Mostra2)
Button2.grid(row=4,column=2, ipadx=5, ipady=5, padx=5, pady=5)
# de dalt a baix.
# no passa si no hi ha res a la caixa de dalt.
def Mostra1(self):
sEntryDalt = self.EntryDalt.get()
if sEntryDalt == '':
tkMessageBox.showinfo("Avís!", "No hi ha text a la caixa superior")
else:
# passa de dalt a baix
self.EntryBaix.delete(0, END)
self.EntryDalt.delete(0, END)
self.EntryBaix.insert(0,sEntryDalt)
# de baix a dalt
# no passa si no hi ha text a la caixa de baix
def Mostra2(self):
sEntryBaix = self.EntryBaix.get()
if sEntryBaix == '':
tkMessageBox.showinfo("Avís!", "No hi ha text a la caixa inferior")
else:
# passa de baix a dalt
self.EntryDalt.delete(0, END)
self.EntryBaix.delete(0, END)
self.EntryDalt.insert(0,sEntryBaix)
if __name__ == "__main__":
root = Tk()
root.title("Prova TK")
App(root)
root.mainloop()
Uns comentaris al codi anterior,
Primer de tot, la importació de les llibreries: he utilitzat Tkinter i tkMessageBox. tkMessageBox em proporciona un popup de missatges que es pot configurar per a que sigui d'informació, d'avís, d'error, amb botons d'OK, Cancel, Sí, no... tkMessageBox no és Tkinter, tot i que també es recolza en Tk per a proporcionar el widget de caixa de missatges.
Segon. M'en vaig al final, al main:
if __name__ == "__main__":
root = Tk()
root.title("Prova Tkinter")
App(root)
root.mainloop()
Primer de tot, cal dir que una interface amb Tk es pot conceptualitzar com un arbre de widgets, en els que uns són fills (estan inclosos) en d'altres, fins arribar a un primer nivell on tindrem un widget arrel. El primer de tot, doncs, és obtenir el widget arrel, amb
root = Tk()
Ara ja puc afegir (incloure) widgets fills.
Un cop tinc el widget arrel, el puc configurar. Per exemple, li dono un títol "Prova Tkinter"
root.title("Prova Tkinter")
A continuació, fent us d'una classe que anomeno App creo la interface.
App(root)
Finalment, inicio l'interface invocant el "bucle d'esdeveniments"
root.mainloop()
Ara és el moment d'analitzar la classe App.
A la classe App he fet que el constructor sigui l'encarregat de col·locar els diferents widgtets a la finestra.
A més, he creat dos mètodes Mostra1 i Mostra2 que seran la resposta als esdeveniments de prémer el botó esquerra i dret respectivament.
Vet aquí el constructor:
def __init__(self, root):
Label(root, text='Caixa superior').grid(row=1,column=1, ipadx=5, ipady=5, padx=5, pady=5)
self.EntryDalt = Entry(root)
self.EntryDalt.grid(row=1,column=2, ipadx=5, ipady=5, padx=5, pady=5)
Label(root, text='Caixa inferior').grid(row=2,column=1, ipadx=5, ipady=5, padx=5, pady=5)
self.EntryBaix = Entry(root)
self.EntryBaix.grid(row=2,column=2, ipadx=5, ipady=5, padx=5, pady=5)
Label(root, text='---------------').grid(row=3,column=1, columnspan=2, ipadx=5, ipady=5, padx=5, pady=5)
Button1 = Button(root, text="Passa de dalt a baix", command=self.Mostra1)
Button1.grid(row=4,column=1, ipadx=5, ipady=5, padx=5, pady=5)
Button2 = Button(root, text="Passa de baix a dalt", command=self.Mostra2)
Button2.grid(row=4,column=2, ipadx=5, ipady=5, padx=5, pady=5)
El que obtinc és
Els constructors dels widgets Label, Entry i Button prenen un primer paràmetre que és el widget pare del que pengen. Labels i Buttons, a més, prenen una paràmetre de configuració que, en aquest cas es refereix al text a mostrar en Labels i Buttons; els buttons, a més, prenent un tercer paràmetre de configuració que fa apunta al mètode que respondrà a l'esdeveniment per defecte del botó, que és fer-hi clic.
Com és que cada widget va al lloc que li correspon? la clau està al mètode grid() El mètode grid ens permet accedir al gestor de finestra Grid. Hi han d'altres tipus de gestor, com el gestor de finestra Pack, o el gestor de Finestra Place.
Grid és molt senzill de fer servir. La forma com ubica els widgets em recorda una mica a la maquetació amb taules en HTML. El mètode grid rep un conjunt de paràmetres. Per exemple:
Label(root, text='Caixa superior').grid(row=1,column=1, ipadx=5, ipady=5, padx=5, pady=5)
Grid conceptualitza la finestra com una graella rectangular de cel·les. Cada cel·la pot acollir un widget. La posició d'una cel·la ve definida per la fila/columna. Les files es numeren de dalt a baix començant per l'1. Les columnes d'esquerra a dreta, començant per l'1. Puc agrupar cel·les adjacents en horitzontal i/o vertical.
Tenint en compte això, els paràmetres del Label "Caixa superior" s'expliquen fàcilment: posa el label a la cel·la de la fila 1, columna 1. L'ample de la cel·la s'ajusta automàticament al contingut. Tanmateix, per a fer que la interfase "respiri" dono un marge interior ("padding") entre el límit de la cel·la i la caixa d'entrada de 5píxels (ipadx=5, ipady=5) i un d'exterior entre cel·les, també de 5 píxels (padx=5, pady=5).
Amb la resta de widgets funciona igual. El resultat és que la meva finestra, conceptualment és una graella de dues columnes per quatre files.
A la fila 3 hi ha un exemple del que deia d'agrupar cel·les adjacents
Label(root, text='---------------').grid(row=3,column=1, columnspan=2, ipadx=5, ipady=5, padx=5, pady=5)
en aquest cas, el paràmetre columnspan em diu que la cel·la ocupa dues cel·les en horitzontal. Hi ha un paràmetre rowspan que funciona de la mateixa forma agrupant cel·les en vertical.
Per acabar, els mètodes que responen als esdeveniments Mostra1 i Mostra2 són gairebé idèntics,
# de dalt a baix.
# no passa si no hi ha res a la caixa de dalt.
def Mostra1(self):
sEntryDalt = self.EntryDalt.get()
if sEntryDalt == '':
tkMessageBox.showinfo("Avís!", "No hi ha text a la caixa superior")
else:
# passa de dalt a baix
self.EntryBaix.delete(0, END)
self.EntryDalt.delete(0, END)
self.EntryBaix.insert(0,sEntryDalt)
# de baix a dalt
# no passa si no hi ha text a la caixa de baix
def Mostra2(self):
sEntryBaix = self.EntryBaix.get()
if sEntryBaix == '':
tkMessageBox.showinfo("Avís!", "No hi ha text a la caixa inferior")
else:
# passa de baix a dalt
self.EntryDalt.delete(0, END)
self.EntryBaix.delete(0, END)
self.EntryDalt.insert(0,sEntryBaix)
A Mostra1, per exemple, primer de tot, s'obté el contingut del EntryDalt amb el mètode get.
sEntryDalt = self.EntryDalt.get()
Si el valor obtingut és nul, mostra l'avís
if sEntryDalt == '':
tkMessageBox.showinfo("Avís!", "No hi ha text a la caixa superior")
En cas contrari, primer esborra les Entry (mètode delete(0,END))
else:
# passa de baix a dalt
self.EntryDalt.delete(0, END)
self.EntryBaix.delete(0, END)
I, finalment, emplena la caixa inferior
self.EntryDalt.insert(0,sEntryBaix)
I fins aquí aquest senzill experiment per a prendre contacte amb Tkinter.
Per a més informació, podeu consultar:
La pàgina de Tkinter, http://www.python.org/topics/tkinter/doc.html
Thinking in Tkinter, http://www.ferg.org/thinking_in_tkinter/index.html
Tkinter: GUI programming with Python, http://infohost.nmt.edu/tcc/help/lang/python/tkinter.html
Python. GUI Programming (Tkinter), http://www.tutorialspoint.com/python/python_gui_programming.htm
Cap comentari:
Publica un comentari a l'entrada