Sorry folks. I found a few bugs in that pasted code of the new and improved tkSimpleDialog. I believe most here could debug it however just in case any newbies are watching i want the code to execute without error.
## START CODE ## import Tkinter as tk MESSAGE = """ You are following bad design patterns. NO SOUP FOR YOU! """ class Dialog(tk.Toplevel): def __init__(self, parent, title='Dialog'): if not isinstance(parent, (tk.Tk, tk.Toplevel)): raise Exception(MESSAGE) """ Initialize a dialog; parent: A Tkinter.Toplevel instance. title: The dialog's title as a string. """ tk.Toplevel.__init__(self, parent) self.withdraw() if parent.winfo_viewable(): # If the parent window is not viewable, don't # make the child transient, or else it would be # opened withdrawn! self.transient(parent) if title: self.title(title) self.parent = parent # self.result is where we store any values for return to # the caller. self.result = None # We save the dialog's main widget frame just incase a # caller needs to access it later. self.frame = tk.Frame(self) # Next we call self.body to create the body of the dialog. # We save the return value as "self.initial_focus" so we # give it focus later. self.initial_focus = self.body(self.frame) self.frame.pack(padx=5, pady=5) self.buttonbox() def show(self): # XXX: Need "show" and "show_modal" methods! self.deiconify() # The window needs to be visible for the grab so we # call wait_visibility and let Tkinter do the waiting # for us. self.wait_visibility() self.grab_set() if not self.initial_focus: self.initial_focus = self self.protocol("WM_DELETE_WINDOW", self.cancel) if self.parent is not None: self.geometry( "+%d+%d" %( self.parent.winfo_rootx()+50, self.parent.winfo_rooty()+50) ) self.initial_focus.focus_set() self.wait_window(self) return self.result def destroy(self): """Destroy the window.""" self.initial_focus = None tk.Toplevel.destroy(self) # # Construction Hooks. # def body(self, master): # XXX: create_body """ OVERIDE: Create dialog body and return widget that should have initial focus. """ pass def buttonbox(self): # XXX: create_buttonbox # XXX: Overiding this method can break funcionality if # you do not properly bind the ok and cancel buttons # correctly! # RFC: Should we create a generic button creation method # or a mixin? """ Add a standard button box; Override if you do not want differnt buttons. """ box = tk.Frame(self) w = tk.Button( box, text="OK", width=10, command=self.ok, default=tk.ACTIVE ) w.pack(side=tk.LEFT, padx=5, pady=5) w = tk.Button( box, text="Cancel", width=10, command=self.cancel ) w.pack(side=tk.LEFT, padx=5, pady=5) self.bind("<Return>", self.ok) self.bind("<Escape>", self.cancel) box.pack() # # Standard Button Callbacks. # def ok(self, event=None): # XXX: okButtonCallback | callbackOkButton | (cb*|*cb) """ Proces the data automatically when user presses ok button.""" if not self.validate(): self.initial_focus.focus_set() # put focus back return self.withdraw() self.update_idletasks() try: self.apply() finally: self.cancel() def cancel(self, event=None): # XXX: cancelButtonCallback | callbackCancelButton | (cb*|*cb) """ Return focus to the parent window and destroy self""" if self.parent is not None: self.parent.focus_set() self.destroy() # # Command Hooks. # def validate(self): # XXX: data_validate """ Validate the data; This method is called automatically to validate the data before the dialog is destroyed. By default, it always validates True. Overide to change behavoir to something more suitabe for your derived dialog. """ return True def apply(self): # XXX: data_process """ Process the data; This method is called automatically to process the data but only *after* the dialog is destroyed. By default, it does nothing. Overide to change the behavoir to something more suitabe for your derived dialog """ pass if __name__ == "__main__": root = tk.Tk() import tkMessageBox ERROR_STR = "We don't have any \"{0}\"!" class MyDialog(Dialog): def body(self, master): self.strvar = tk.StringVar(master, "Eggs") self.label = tk.Label(self, text='Default') self.label.pack() self.options = tk.OptionMenu( self, self.strvar, "Jam", "Ham", "Spam", ) self.options.pack() def validate(self): text = self.strvar.get() if text and text.lower() != 'spam': tkMessageBox.showerror( 'Order Error', ERROR_STR.format(text), parent=self ) return False return True def apply(self): self.result = self.strvar.get() m = MyDialog(root, title='Menu = spam') # Test changing widget values after initialization. m.label['text'] = 'What would you like to order?' # Show the modal dialog. result = m.show() print 'User Choose: {0}'.format(result) root.mainloop() ## END CODE ## -- http://mail.python.org/mailman/listinfo/python-list