0001 # 0002 # An Introduction to Tkinter 0003 # tkSimpleDialog.py 0004 # 0005 # Copyright (c) 1997 by Fredrik Lundh 0006 # 0007 # fredrik@pythonware.com 0008 # http://www.pythonware.com 0009 # 0010 0011 # -------------------------------------------------------------------- 0012 # dialog base class 0013 0014 '''Dialog boxes 0015 0016 This module handles dialog boxes. It contains the following 0017 public symbols: 0018 0019 Dialog -- a base class for dialogs 0020 0021 askinteger -- get an integer from the user 0022 0023 askfloat -- get a float from the user 0024 0025 askstring -- get a string from the user 0026 ''' 0027 0028 from Tkinter import * 0029 import os 0030 0031 class Dialog(Toplevel): 0032 0033 '''Class to open dialogs. 0034 0035 This class is intended as a base class for custom dialogs 0036 ''' 0037 0038 def __init__(self, parent, title = None): 0039 0040 '''Initialize a dialog. 0041 0042 Arguments: 0043 0044 parent -- a parent window (the application window) 0045 0046 title -- the dialog title 0047 ''' 0048 Toplevel.__init__(self, parent) 0049 self.transient(parent) 0050 0051 if title: 0052 self.title(title) 0053 0054 self.parent = parent 0055 0056 self.result = None 0057 0058 body = Frame(self) 0059 self.initial_focus = self.body(body) 0060 body.pack(padx=5, pady=5) 0061 0062 self.buttonbox() 0063 0064 self.wait_visibility() # window needs to be visible for the grab 0065 self.grab_set() 0066 0067 if not self.initial_focus: 0068 self.initial_focus = self 0069 0070 self.protocol("WM_DELETE_WINDOW", self.cancel) 0071 0072 if self.parent is not None: 0073 self.geometry("+%d+%d" % (parent.winfo_rootx()+50, 0074 parent.winfo_rooty()+50)) 0075 0076 self.initial_focus.focus_set() 0077 0078 self.wait_window(self) 0079 0080 def destroy(self): 0081 '''Destroy the window''' 0082 self.initial_focus = None 0083 Toplevel.destroy(self) 0084 0085 # 0086 # construction hooks 0087 0088 def body(self, master): 0089 '''create dialog body. 0090 0091 return widget that should have initial focus. 0092 This method should be overridden, and is called 0093 by the __init__ method. 0094 ''' 0095 pass 0096 0097 def buttonbox(self): 0098 '''add standard button box. 0099 0100 override if you do not want the standard buttons 0101 ''' 0102 0103 box = Frame(self) 0104 0105 w = Button(box, text="OK", width=10, command=self.ok, default=ACTIVE) 0106 w.pack(side=LEFT, padx=5, pady=5) 0107 w = Button(box, text="Cancel", width=10, command=self.cancel) 0108 w.pack(side=LEFT, padx=5, pady=5) 0109 0110 self.bind("<Return>", self.ok) 0111 self.bind("<Escape>", self.cancel) 0112 0113 box.pack() 0114 0115 # 0116 # standard button semantics 0117 0118 def ok(self, event=None): 0119 0120 if not self.validate(): 0121 self.initial_focus.focus_set() # put focus back 0122 return 0123 0124 self.withdraw() 0125 self.update_idletasks() 0126 0127 self.apply() 0128 0129 self.cancel() 0130 0131 def cancel(self, event=None): 0132 0133 # put focus back to the parent window 0134 if self.parent is not None: 0135 self.parent.focus_set() 0136 self.destroy() 0137 0138 # 0139 # command hooks 0140 0141 def validate(self): 0142 '''validate the data 0143 0144 This method is called automatically to validate the data before the 0145 dialog is destroyed. By default, it always validates OK. 0146 ''' 0147 0148 return 1 # override 0149 0150 def apply(self): 0151 '''process the data 0152 0153 This method is called automatically to process the data, *after* 0154 the dialog is destroyed. By default, it does nothing. 0155 ''' 0156 0157 pass # override 0158 0159 0160 # -------------------------------------------------------------------- 0161 # convenience dialogues 0162 0163 class _QueryDialog(Dialog): 0164 0165 def __init__(self, title, prompt, 0166 initialvalue=None, 0167 minvalue = None, maxvalue = None, 0168 parent = None): 0169 0170 if not parent: 0171 import Tkinter 0172 parent = Tkinter._default_root 0173 0174 self.prompt = prompt 0175 self.minvalue = minvalue 0176 self.maxvalue = maxvalue 0177 0178 self.initialvalue = initialvalue 0179 0180 Dialog.__init__(self, parent, title) 0181 0182 def destroy(self): 0183 self.entry = None 0184 Dialog.destroy(self) 0185 0186 def body(self, master): 0187 0188 w = Label(master, text=self.prompt, justify=LEFT) 0189 w.grid(row=0, padx=5, sticky=W) 0190 0191 self.entry = Entry(master, name="entry") 0192 self.entry.grid(row=1, padx=5, sticky=W+E) 0193 0194 if self.initialvalue: 0195 self.entry.insert(0, self.initialvalue) 0196 self.entry.select_range(0, END) 0197 0198 return self.entry 0199 0200 def validate(self): 0201 0202 import tkMessageBox 0203 0204 try: 0205 result = self.getresult() 0206 except ValueError: 0207 tkMessageBox.showwarning( 0208 "Illegal value", 0209 self.errormessage + "\nPlease try again", 0210 parent = self 0211 ) 0212 return 0 0213 0214 if self.minvalue is not None and result < self.minvalue: 0215 tkMessageBox.showwarning( 0216 "Too small", 0217 "The allowed minimum value is %s. " 0218 "Please try again." % self.minvalue, 0219 parent = self 0220 ) 0221 return 0 0222 0223 if self.maxvalue is not None and result > self.maxvalue: 0224 tkMessageBox.showwarning( 0225 "Too large", 0226 "The allowed maximum value is %s. " 0227 "Please try again." % self.maxvalue, 0228 parent = self 0229 ) 0230 return 0 0231 0232 self.result = result 0233 0234 return 1 0235 0236 0237 class _QueryInteger(_QueryDialog): 0238 errormessage = "Not an integer." 0239 def getresult(self): 0240 return int(self.entry.get()) 0241 0242 def askinteger(title, prompt, **kw): 0243 '''get an integer from the user 0244 0245 Arguments: 0246 0247 title -- the dialog title 0248 prompt -- the label text 0249 **kw -- see SimpleDialog class 0250 0251 Return value is an integer 0252 ''' 0253 d = _QueryInteger(title, prompt, **kw) 0254 return d.result 0255 0256 class _QueryFloat(_QueryDialog): 0257 errormessage = "Not a floating point value." 0258 def getresult(self): 0259 return float(self.entry.get()) 0260 0261 def askfloat(title, prompt, **kw): 0262 '''get a float from the user 0263 0264 Arguments: 0265 0266 title -- the dialog title 0267 prompt -- the label text 0268 **kw -- see SimpleDialog class 0269 0270 Return value is a float 0271 ''' 0272 d = _QueryFloat(title, prompt, **kw) 0273 return d.result 0274 0275 class _QueryString(_QueryDialog): 0276 def __init__(self, *args, **kw): 0277 if kw.has_key("show"): 0278 self.__show = kw["show"] 0279 del kw["show"] 0280 else: 0281 self.__show = None 0282 _QueryDialog.__init__(self, *args, **kw) 0283 0284 def body(self, master): 0285 entry = _QueryDialog.body(self, master) 0286 if self.__show is not None: 0287 entry.configure(show=self.__show) 0288 return entry 0289 0290 def getresult(self): 0291 return self.entry.get() 0292 0293 def askstring(title, prompt, **kw): 0294 '''get a string from the user 0295 0296 Arguments: 0297 0298 title -- the dialog title 0299 prompt -- the label text 0300 **kw -- see SimpleDialog class 0301 0302 Return value is a string 0303 ''' 0304 d = _QueryString(title, prompt, **kw) 0305 return d.result 0306 0307 if __name__ == "__main__": 0308 0309 root = Tk() 0310 root.update() 0311 0312 print askinteger("Spam", "Egg count", initialvalue=12*12) 0313 print askfloat("Spam", "Egg weight\n(in tons)", minvalue=1, maxvalue=100) 0314 print askstring("Spam", "Egg label") 0315
Generated by PyXR 0.9.4