blob: c297922a635d37d0776abd50ac3aad6315d21d0d [file] [log] [blame]
Guido van Rossumf55afae1997-08-12 18:21:21 +00001#
2# An Introduction to Tkinter
3# tkSimpleDialog.py
4#
5# Copyright (c) 1997 by Fredrik Lundh
6#
7# fredrik@pythonware.com
8# http://www.pythonware.com
9#
10
11# --------------------------------------------------------------------
12# dialog base class
13
14from Tkinter import *
15import os
16
17class Dialog(Toplevel):
18
19 def __init__(self, parent, title = None):
20
21 Toplevel.__init__(self, parent)
22 self.transient(parent)
23
24 if title:
25 self.title(title)
26
27 self.parent = parent
28
29 self.result = None
30
31 body = Frame(self)
32 self.initial_focus = self.body(body)
33 body.pack(padx=5, pady=5)
34
35 self.buttonbox()
36
37 self.grab_set()
38
39 if not self.initial_focus:
40 self.initial_focus = self
41
42 self.protocol("WM_DELETE_WINDOW", self.cancel)
43
44 self.geometry("+%d+%d" % (parent.winfo_rootx()+50,
45 parent.winfo_rooty()+50))
46
47 self.initial_focus.focus_set()
48
49 self.wait_window(self)
50
51 #
52 # construction hooks
53
54 def body(self, master):
55 # create dialog body. return widget that should have
56 # initial focus. this method should be overridden
57
58 pass
59
60 def buttonbox(self):
61 # add standard button box. override if you don't want the
62 # standard buttons
63
64 box = Frame(self)
65
66 w = Button(box, text="OK", width=10, command=self.ok, default=ACTIVE)
67 w.pack(side=LEFT, padx=5, pady=5)
68 w = Button(box, text="Cancel", width=10, command=self.cancel)
69 w.pack(side=LEFT, padx=5, pady=5)
70
71 self.bind("<Return>", self.ok)
72 self.bind("<Escape>", self.cancel)
73
74 box.pack()
75
76 #
77 # standard button semantics
78
79 def ok(self, event=None):
80
81 if not self.validate():
82 self.initial_focus.focus_set() # put focus back
83 return
84
85 self.withdraw()
86 self.update_idletasks()
87
88 self.apply()
89
90 self.cancel()
91
92 def cancel(self, event=None):
93
94 # put focus back to the parent window
95 self.parent.focus_set()
96 self.destroy()
97
98 #
99 # command hooks
100
101 def validate(self):
102
103 return 1 # override
104
105 def apply(self):
106
107 pass # override
108
109
110# --------------------------------------------------------------------
111# convenience dialogues
112
113import string
114
115class _QueryDialog(Dialog):
116
117 def __init__(self, title, prompt,
Guido van Rossum1530c871997-08-14 14:17:28 +0000118 initialvalue=None,
Guido van Rossumf55afae1997-08-12 18:21:21 +0000119 minvalue = None, maxvalue = None,
120 parent = None):
121
122 from Tkinter import _default_root
123
124 if not parent:
125 parent = _default_root
126
127 self.prompt = prompt
128 self.minvalue = minvalue
129 self.maxvalue = maxvalue
130
Guido van Rossum1530c871997-08-14 14:17:28 +0000131 self.initialvalue = initialvalue
132
Guido van Rossumf55afae1997-08-12 18:21:21 +0000133 Dialog.__init__(self, parent, title)
134
135 def body(self, master):
136
Guido van Rossum1530c871997-08-14 14:17:28 +0000137 w = Label(master, text=self.prompt, justify=LEFT)
Guido van Rossumf55afae1997-08-12 18:21:21 +0000138 w.grid(row=0, padx=5, sticky=W)
139
140 self.entry = Entry(master, name="entry")
141 self.entry.grid(row=1, padx=5, sticky=W+E)
142
Guido van Rossum1530c871997-08-14 14:17:28 +0000143 if self.initialvalue:
144 self.entry.insert(0, self.initialvalue)
145 self.entry.select_range(0, END)
146
Guido van Rossumf55afae1997-08-12 18:21:21 +0000147 return self.entry
148
149 def validate(self):
150
151 import tkMessageBox
152
153 try:
154 result = self.getresult()
155 except ValueError:
156 tkMessageBox.showwarning(
Guido van Rossum1530c871997-08-14 14:17:28 +0000157 "Illegal value",
Guido van Rossumf55afae1997-08-12 18:21:21 +0000158 self.errormessage + "\nPlease try again",
159 parent = self
160 )
161 return 0
162
163 if self.minvalue is not None and result < self.minvalue:
164 tkMessageBox.showwarning(
165 "Too small",
166 "The allowed minimum value is %s. "
Guido van Rossum1530c871997-08-14 14:17:28 +0000167 "Please try again." % self.minvalue,
Guido van Rossumf55afae1997-08-12 18:21:21 +0000168 parent = self
169 )
170 return 0
171
172 if self.maxvalue is not None and result > self.maxvalue:
173 tkMessageBox.showwarning(
Guido van Rossum1530c871997-08-14 14:17:28 +0000174 "Too large",
Guido van Rossumf55afae1997-08-12 18:21:21 +0000175 "The allowed maximum value is %s. "
Guido van Rossum1530c871997-08-14 14:17:28 +0000176 "Please try again." % self.maxvalue,
Guido van Rossumf55afae1997-08-12 18:21:21 +0000177 parent = self
178 )
179 return 0
180
181 self.result = result
182
183 return 1
184
185
186class _QueryInteger(_QueryDialog):
Guido van Rossum1530c871997-08-14 14:17:28 +0000187 errormessage = "Not an integer."
Guido van Rossumf55afae1997-08-12 18:21:21 +0000188 def getresult(self):
189 return string.atoi(self.entry.get())
190
191def askinteger(title, prompt, **kw):
192 d = apply(_QueryInteger, (title, prompt), kw)
193 return d.result
194
195class _QueryFloat(_QueryDialog):
Guido van Rossum1530c871997-08-14 14:17:28 +0000196 errormessage = "Not a floating point value."
Guido van Rossumf55afae1997-08-12 18:21:21 +0000197 def getresult(self):
198 return string.atof(self.entry.get())
199
200def askfloat(title, prompt, **kw):
201 d = apply(_QueryFloat, (title, prompt), kw)
202 return d.result
203
204class _QueryString(_QueryDialog):
205 def getresult(self):
206 return self.entry.get()
207
208def askstring(title, prompt, **kw):
209 d = apply(_QueryString, (title, prompt), kw)
210 return d.result
211
212if __name__ == "__main__":
213
214 root = Tk()
215 root.update()
216
Guido van Rossum1530c871997-08-14 14:17:28 +0000217 print askinteger("Spam", "Egg count", initialvalue=12*12)
218 print askfloat("Spam", "Egg weight\n(in tons)", minvalue=1, maxvalue=100)
Guido van Rossumf55afae1997-08-12 18:21:21 +0000219 print askstring("Spam", "Egg label")
Guido van Rossum1530c871997-08-14 14:17:28 +0000220