2 # An Introduction to Tkinter
5 # Copyright (c) 1997 by Fredrik Lundh
7 # fredrik@pythonware.com
8 # http://www.pythonware.com
11 # --------------------------------------------------------------------
16 This module handles dialog boxes. It contains the following
19 Dialog -- a base class for dialogs
21 askinteger -- get an integer from the user
23 askfloat -- get a float from the user
25 askstring -- get a string from the user
30 class Dialog(Toplevel
):
32 '''Class to open dialogs.
34 This class is intended as a base class for custom dialogs
37 def __init__(self
, parent
, title
= None):
39 '''Initialize a dialog.
43 parent -- a parent window (the application window)
45 title -- the dialog title
47 Toplevel
.__init
__(self
, parent
)
49 self
.withdraw() # remain invisible for now
50 # If the master is not viewable, don't
51 # make the child transient, or else it
52 # would be opened withdrawn
53 if parent
.winfo_viewable():
54 self
.transient(parent
)
64 self
.initial_focus
= self
.body(body
)
65 body
.pack(padx
=5, pady
=5)
70 if not self
.initial_focus
:
71 self
.initial_focus
= self
73 self
.protocol("WM_DELETE_WINDOW", self
.cancel
)
75 if self
.parent
is not None:
76 self
.geometry("+%d+%d" % (parent
.winfo_rootx()+50,
77 parent
.winfo_rooty()+50))
79 self
.deiconify() # become visibile now
81 self
.initial_focus
.focus_set()
83 # wait for window to appear on screen before calling grab_set
84 self
.wait_visibility()
86 self
.wait_window(self
)
89 '''Destroy the window'''
90 self
.initial_focus
= None
91 Toplevel
.destroy(self
)
96 def body(self
, master
):
97 '''create dialog body.
99 return widget that should have initial focus.
100 This method should be overridden, and is called
101 by the __init__ method.
106 '''add standard button box.
108 override if you do not want the standard buttons
113 w
= Button(box
, text
="OK", width
=10, command
=self
.ok
, default
=ACTIVE
)
114 w
.pack(side
=LEFT
, padx
=5, pady
=5)
115 w
= Button(box
, text
="Cancel", width
=10, command
=self
.cancel
)
116 w
.pack(side
=LEFT
, padx
=5, pady
=5)
118 self
.bind("<Return>", self
.ok
)
119 self
.bind("<Escape>", self
.cancel
)
124 # standard button semantics
126 def ok(self
, event
=None):
128 if not self
.validate():
129 self
.initial_focus
.focus_set() # put focus back
133 self
.update_idletasks()
140 def cancel(self
, event
=None):
142 # put focus back to the parent window
143 if self
.parent
is not None:
144 self
.parent
.focus_set()
153 This method is called automatically to validate the data before the
154 dialog is destroyed. By default, it always validates OK.
162 This method is called automatically to process the data, *after*
163 the dialog is destroyed. By default, it does nothing.
169 # --------------------------------------------------------------------
170 # convenience dialogues
172 class _QueryDialog(Dialog
):
174 def __init__(self
, title
, prompt
,
176 minvalue
= None, maxvalue
= None,
181 parent
= Tkinter
._default
_root
184 self
.minvalue
= minvalue
185 self
.maxvalue
= maxvalue
187 self
.initialvalue
= initialvalue
189 Dialog
.__init
__(self
, parent
, title
)
195 def body(self
, master
):
197 w
= Label(master
, text
=self
.prompt
, justify
=LEFT
)
198 w
.grid(row
=0, padx
=5, sticky
=W
)
200 self
.entry
= Entry(master
, name
="entry")
201 self
.entry
.grid(row
=1, padx
=5, sticky
=W
+E
)
203 if self
.initialvalue
:
204 self
.entry
.insert(0, self
.initialvalue
)
205 self
.entry
.select_range(0, END
)
214 result
= self
.getresult()
216 tkMessageBox
.showwarning(
218 self
.errormessage
+ "\nPlease try again",
223 if self
.minvalue
is not None and result
< self
.minvalue
:
224 tkMessageBox
.showwarning(
226 "The allowed minimum value is %s. "
227 "Please try again." % self
.minvalue
,
232 if self
.maxvalue
is not None and result
> self
.maxvalue
:
233 tkMessageBox
.showwarning(
235 "The allowed maximum value is %s. "
236 "Please try again." % self
.maxvalue
,
246 class _QueryInteger(_QueryDialog
):
247 errormessage
= "Not an integer."
249 return int(self
.entry
.get())
251 def askinteger(title
, prompt
, **kw
):
252 '''get an integer from the user
256 title -- the dialog title
257 prompt -- the label text
258 **kw -- see SimpleDialog class
260 Return value is an integer
262 d
= _QueryInteger(title
, prompt
, **kw
)
265 class _QueryFloat(_QueryDialog
):
266 errormessage
= "Not a floating point value."
268 return float(self
.entry
.get())
270 def askfloat(title
, prompt
, **kw
):
271 '''get a float from the user
275 title -- the dialog title
276 prompt -- the label text
277 **kw -- see SimpleDialog class
279 Return value is a float
281 d
= _QueryFloat(title
, prompt
, **kw
)
284 class _QueryString(_QueryDialog
):
285 def __init__(self
, *args
, **kw
):
287 self
.__show
= kw
["show"]
291 _QueryDialog
.__init
__(self
, *args
, **kw
)
293 def body(self
, master
):
294 entry
= _QueryDialog
.body(self
, master
)
295 if self
.__show
is not None:
296 entry
.configure(show
=self
.__show
)
300 return self
.entry
.get()
302 def askstring(title
, prompt
, **kw
):
303 '''get a string from the user
307 title -- the dialog title
308 prompt -- the label text
309 **kw -- see SimpleDialog class
311 Return value is a string
313 d
= _QueryString(title
, prompt
, **kw
)
316 if __name__
== "__main__":
321 print askinteger("Spam", "Egg count", initialvalue
=12*12)
322 print askfloat("Spam", "Egg weight\n(in tons)", minvalue
=1, maxvalue
=100)
323 print askstring("Spam", "Egg label")