Receita: Tkinter e Shelve
Um pequeno exemplo de cadastro (agenda) utilizando Tkinter para a interface GUI e Shelve para a persistência dos objetos. É um software de exemplo e pode (deve) sofrer melhorias. Além disso, é uma boa prática de programação OO separar os objetos de interface dos objetos de negócio. Eu não fiz isso neste exemplo.
Este exemplo apareceu na lista python-brasil@yahoogroups.com.br.
Código
1 #!/usr/bin/env python
2 # -*- coding: ISO-8859-1 -*-
3 # agenda.py
4
5 from Tkinter import *
6 from Dialog import Dialog
7 import shelve
8
9 class MainFrame(Frame):
10 def __init__(self, parent=None):
11 Frame.__init__(self, parent)
12 self.grid()
13 self.createWidgets()
14 self.master.title("Cadastro de amigos")
15
16 def createWidgets(self):
17 self.makeScreen()
18 self.makeToolBar()
19
20 def makeScreen(self):
21 self.nome = StringVar()
22 self.endereco = StringVar()
23 self.telefone = StringVar()
24
25 Label(self, text="Nome:").grid(row=1, sticky=W)
26 Label(self, text="Endereço:").grid(row=2, sticky=W)
27 Label(self, text="Telefone:").grid(row=3, sticky=W)
28
29 Entry(self, textvariable=self.nome).grid( \
30 row=1, column=1, sticky=W+E)
31 Entry(self, textvariable=self.endereco).grid( \
32 row=2, column=1, sticky=W+E)
33 Entry(self, textvariable=self.telefone).grid( \
34 row=3, column=1, sticky=W+E)
35
36 def makeToolBar(self):
37 toolbar = Frame(self)
38 toolbar.grid(row=4, columnspan=2)
39
40 Button(toolbar, text="Adicionar", \
41 command=self.adicionar).grid(row=0,column=0)
42 Button(toolbar, text="Gravar", \
43 command=self.gravar).grid(row=0,column=1)
44 Button(toolbar, text="Remover", \
45 command=self.remover).grid(row=0,column=2)
46 Button(toolbar, text="Procurar", \
47 command=self.procurar).grid(row=0,column=3)
48 Button(toolbar, text="Listar", \
49 command=self.listar).grid(row=0,column=4)
50 Button(toolbar, text="Sair", \
51 command=self.sair).grid(row=0,column=5)
52
53 def adicionar(self):
54 nome = self.nome.get()
55 if not len(nome):
56 Dialog(self, title="Erro!", text="Nome inválido", \
57 bitmap='error', default=0, strings=('OK',))
58 return
59
60 if self.db.has_key(nome):
61 Dialog(self, title="Erro!", text="Nome já cadastrado", \
62 bitmap='error', default=0, strings=('OK',))
63 return
64
65 self.db[nome] = (self.endereco.get(), self.telefone.get())
66 self.limpaCampos()
67
68 def gravar(self):
69 nome = self.nome.get()
70 if not len(nome):
71 Dialog(self, title="Erro!", text="Nome inválido",
72 bitmap='error', default=0, strings=('OK',))
73 return
74
75 if not self.db.has_key(nome):
76 Dialog(self, title="Erro!", \
77 text="Nome inexistente, use o botão adicionar", \
78 bitmap='error', default=0, strings=('OK',))
79 return
80
81 self.db[nome] = (self.endereco.get(), self.telefone.get())
82 self.limpaCampos()
83
84 def limpaCampos(self):
85 self.nome.set("")
86 self.telefone.set("")
87 self.endereco.set("")
88
89 def procurar(self):
90 nome = self.nome.get()
91 if not len(nome):
92 Dialog(self, title="Erro!", text="Nome inválido", \
93 bitmap='error', default=0, strings=('OK',))
94 return
95
96 if not self.db.has_key(nome):
97 Dialog(self, title="Erro!", text="Nome não encontrado", \
98 bitmap='error', default=0, strings=('OK',))
99 return
100
101 self.telefone.set(self.db.get(nome, "")[0])
102 self.endereco.set(self.db.get(nome, "")[1])
103
104 def remover(self):
105 nome = self.nome.get()
106 if not len(nome):
107 Dialog(self, title="Erro!", text="Nome inválido", \
108 bitmap='error', default=0, strings=('OK',))
109 return
110
111 if not self.db.has_key(nome):
112 Dialog(self, title="Erro!", text="Nome não encontrado", \
113 bitmap='error', default=0, strings=('OK',))
114 return
115
116 self.telefone.set(self.db.get(nome, "")[0])
117 self.endereco.set(self.db.get(nome, "")[1])
118
119 resposta = Dialog(self, title="Confirmação", \
120 text="Deseja remover?", \
121 bitmap='question', default=1, strings=('Sim', 'Não'))
122 if resposta.num == 0:
123 del self.db[nome]
124 self.limpaCampos()
125
126 def listar(self):
127 print "%-30s | %-20s | %-10s" % ("Nome", "Endereço", "Telefone")
128 print "%-30s-+-%-20s-+-%-10s" % ("-" * 30, "-" * 20, "-" * 10)
129 for k in self.db.keys():
130 print "%-30s | %-20s | %-10s" % (k, self.db[k][0], \
131 self.db[k][1])
132 print
133
134 def sair(self):
135 resposta = Dialog(self, title="Confirmação", \
136 text="Tem certeza que deseja sair?", \
137 bitmap='question', default=1, \
138 strings=('Sim', 'Não'))
139 if resposta.num == 0: self.quit()
140
141 def setDB(self, db):
142 self.db = db
143
144 def main():
145 db = shelve.open("teste.db")
146 frm = MainFrame()
147 frm.setDB(db)
148 frm.mainloop()
149 print "saindo..."
150 db.close()
151
152 if __name__ == '__main__':
153 main()
Usando
$ python agenda.py
ou
$ chmod +x agenda.py $ ./agenda.py
Volta para CookBook.