| 
									
										
										
										
											1996-11-27 19:52:01 +00:00
										 |  |  | #! /usr/bin/env python | 
					
						
							| 
									
										
										
										
											1995-03-02 14:05:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # A Python function that generates dialog boxes with a text message, | 
					
						
							|  |  |  | # optional bitmap, and any number of buttons. | 
					
						
							|  |  |  | # Cf. Ousterhout, Tcl and the Tk Toolkit, Figs. 27.2-3, pp. 269-270. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from Tkinter import * | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | mainWidget = None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def dialog(master, title, text, bitmap, default, *args): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # 1. Create the top-level window and divide it into top | 
					
						
							|  |  |  |     # and bottom parts. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     w = Toplevel(master, {'class': 'Dialog'}) | 
					
						
							|  |  |  |     w.title(title) | 
					
						
							|  |  |  |     w.iconname('Dialog') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     top = Frame(w, {'relief': 'raised', 'bd': 1, | 
					
						
							| 
									
										
										
										
											1998-04-10 19:15:27 +00:00
										 |  |  |                     Pack: {'side': 'top', 'fill': 'both'}}) | 
					
						
							| 
									
										
										
										
											1995-03-02 14:05:29 +00:00
										 |  |  |     bot = Frame(w, {'relief': 'raised', 'bd': 1, | 
					
						
							| 
									
										
										
										
											1998-04-10 19:15:27 +00:00
										 |  |  |                     Pack: {'side': 'bottom', 'fill': 'both'}}) | 
					
						
							| 
									
										
										
										
											1995-03-02 14:05:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # 2. Fill the top part with the bitmap and message. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     msg = Message(top, | 
					
						
							| 
									
										
										
										
											1998-04-10 19:15:27 +00:00
										 |  |  |                   {'width': '3i', | 
					
						
							|  |  |  |                    'text': text, | 
					
						
							|  |  |  |                    'font': '-Adobe-Times-Medium-R-Normal-*-180-*', | 
					
						
							|  |  |  |                    Pack: {'side': 'right', 'expand': 1, | 
					
						
							|  |  |  |                           'fill': 'both', | 
					
						
							|  |  |  |                           'padx': '3m', 'pady': '3m'}}) | 
					
						
							| 
									
										
										
										
											1995-03-02 14:05:29 +00:00
										 |  |  |     if bitmap: | 
					
						
							| 
									
										
										
										
											1998-04-10 19:15:27 +00:00
										 |  |  |         bm = Label(top, {'bitmap': bitmap, | 
					
						
							|  |  |  |                          Pack: {'side': 'left', | 
					
						
							|  |  |  |                                 'padx': '3m', 'pady': '3m'}}) | 
					
						
							| 
									
										
										
										
											1995-03-02 14:05:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # 3. Create a row of buttons at the bottom of the dialog. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     buttons = [] | 
					
						
							|  |  |  |     i = 0 | 
					
						
							|  |  |  |     for but in args: | 
					
						
							| 
									
										
										
										
											1998-04-10 19:15:27 +00:00
										 |  |  |         b = Button(bot, {'text': but, | 
					
						
							|  |  |  |                          'command': ('set', 'button', i)}) | 
					
						
							|  |  |  |         buttons.append(b) | 
					
						
							|  |  |  |         if i == default: | 
					
						
							|  |  |  |             bd = Frame(bot, {'relief': 'sunken', 'bd': 1, | 
					
						
							|  |  |  |                              Pack: {'side': 'left', 'expand': 1, | 
					
						
							|  |  |  |                                     'padx': '3m', 'pady': '2m'}}) | 
					
						
							|  |  |  |             b.lift() | 
					
						
							|  |  |  |             b.pack ({'in': bd, 'side': 'left', | 
					
						
							|  |  |  |                      'padx': '2m', 'pady': '2m', | 
					
						
							|  |  |  |                      'ipadx': '2m', 'ipady': '1m'}) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             b.pack ({'side': 'left', 'expand': 1, | 
					
						
							|  |  |  |                      'padx': '3m', 'pady': '3m', | 
					
						
							|  |  |  |                      'ipady': '2m', 'ipady': '1m'}) | 
					
						
							|  |  |  |         i = i+1 | 
					
						
							| 
									
										
										
										
											1995-03-02 14:05:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # 4. Set up a binding for <Return>, if there's a default, | 
					
						
							|  |  |  |     # set a grab, and claim the focus too. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if default >= 0: | 
					
						
							| 
									
										
										
										
											1998-04-10 19:15:27 +00:00
										 |  |  |         w.bind('<Return>', | 
					
						
							|  |  |  |                lambda e, b=buttons[default], i=default: | 
					
						
							|  |  |  |                (b.flash(), | 
					
						
							|  |  |  |                 b.setvar('button', i))) | 
					
						
							| 
									
										
										
										
											1995-03-02 14:05:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     oldFocus = w.tk.call('focus') # XXX | 
					
						
							|  |  |  |     w.grab_set() | 
					
						
							|  |  |  |     w.focus() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # 5. Wait for the user to respond, then restore the focus | 
					
						
							|  |  |  |     # and return the index of the selected button. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     w.waitvar('button') | 
					
						
							|  |  |  |     w.destroy() | 
					
						
							|  |  |  |     w.tk.call('focus', oldFocus) # XXX | 
					
						
							|  |  |  |     return w.getint(w.getvar('button')) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def strdialog(master, title, text, bitmap, default, *args): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # 1. Create the top-level window and divide it into top | 
					
						
							|  |  |  |     # and bottom parts. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     w = Toplevel(master, {'class': 'Dialog'}) | 
					
						
							|  |  |  |     w.title(title) | 
					
						
							|  |  |  |     w.iconname('Dialog') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     top = Frame(w, {'relief': 'raised', 'bd': 1, | 
					
						
							| 
									
										
										
										
											1998-04-10 19:15:27 +00:00
										 |  |  |                     Pack: {'side': 'top', 'fill': 'both'}}) | 
					
						
							| 
									
										
										
										
											1995-03-02 14:05:29 +00:00
										 |  |  |     if args: | 
					
						
							| 
									
										
										
										
											1998-04-10 19:15:27 +00:00
										 |  |  |         bot = Frame(w, {'relief': 'raised', 'bd': 1, | 
					
						
							|  |  |  |                     Pack: {'side': 'bottom', 'fill': 'both'}}) | 
					
						
							| 
									
										
										
										
											1995-03-02 14:05:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # 2. Fill the top part with the bitmap, message and input field. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if bitmap: | 
					
						
							| 
									
										
										
										
											1998-04-10 19:15:27 +00:00
										 |  |  |         bm = Label(top, {'bitmap': bitmap, | 
					
						
							|  |  |  |                          Pack: {'side': 'left', | 
					
						
							|  |  |  |                                 'padx': '3m', 'pady': '3m'}}) | 
					
						
							| 
									
										
										
										
											1995-03-02 14:05:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     msg = Message(top, | 
					
						
							| 
									
										
										
										
											1998-04-10 19:15:27 +00:00
										 |  |  |                   {'width': '3i', | 
					
						
							|  |  |  |                    'text': text, | 
					
						
							|  |  |  |                    'font': '-Adobe-Times-Medium-R-Normal-*-180-*', | 
					
						
							|  |  |  |                    Pack: {'side': 'left',  | 
					
						
							|  |  |  |                           'fill': 'both', | 
					
						
							|  |  |  |                           'padx': '3m', 'pady': '3m'}}) | 
					
						
							| 
									
										
										
										
											1995-03-02 14:05:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     field = Entry(top, | 
					
						
							| 
									
										
										
										
											1998-04-10 19:15:27 +00:00
										 |  |  |                   {'relief':'sunken', | 
					
						
							|  |  |  |                    Pack:{'side':'left', | 
					
						
							|  |  |  |                          'fill':'x', | 
					
						
							|  |  |  |                          'expand':1, | 
					
						
							|  |  |  |                          'padx':'3m', 'pady':'3m'}}) | 
					
						
							| 
									
										
										
										
											1995-03-02 14:05:29 +00:00
										 |  |  |     # 3. Create a row of buttons at the bottom of the dialog. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     buttons = [] | 
					
						
							|  |  |  |     i = 0 | 
					
						
							|  |  |  |     for but in args: | 
					
						
							| 
									
										
										
										
											1998-04-10 19:15:27 +00:00
										 |  |  |         b = Button(bot, {'text': but, | 
					
						
							|  |  |  |                          'command': ('set', 'button', i)}) | 
					
						
							|  |  |  |         buttons.append(b) | 
					
						
							|  |  |  |         if i == default: | 
					
						
							|  |  |  |             bd = Frame(bot, {'relief': 'sunken', 'bd': 1, | 
					
						
							|  |  |  |                              Pack: {'side': 'left', 'expand': 1, | 
					
						
							|  |  |  |                                     'padx': '3m', 'pady': '2m'}}) | 
					
						
							|  |  |  |             b.lift() | 
					
						
							|  |  |  |             b.pack ({'in': bd, 'side': 'left', | 
					
						
							|  |  |  |                      'padx': '2m', 'pady': '2m', | 
					
						
							|  |  |  |                      'ipadx': '2m', 'ipady': '1m'}) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             b.pack ({'side': 'left', 'expand': 1, | 
					
						
							|  |  |  |                      'padx': '3m', 'pady': '3m', | 
					
						
							|  |  |  |                      'ipady': '2m', 'ipady': '1m'}) | 
					
						
							|  |  |  |         i = i+1 | 
					
						
							| 
									
										
										
										
											1995-03-02 14:05:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # 4. Set up a binding for <Return>, if there's a default, | 
					
						
							|  |  |  |     # set a grab, and claim the focus too. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if not args: | 
					
						
							| 
									
										
										
										
											1998-04-10 19:15:27 +00:00
										 |  |  |         w.bind('<Return>', lambda arg, top=top: top.setvar('button', 0)) | 
					
						
							|  |  |  |         field.bind('<Return>', lambda arg, top=top: top.setvar('button', 0)) | 
					
						
							| 
									
										
										
										
											1995-03-02 14:05:29 +00:00
										 |  |  |     elif default >= 0: | 
					
						
							| 
									
										
										
										
											1998-04-10 19:15:27 +00:00
										 |  |  |         w.bind('<Return>', | 
					
						
							|  |  |  |                lambda e, b=buttons[default], i=default: | 
					
						
							|  |  |  |                (b.flash(), | 
					
						
							|  |  |  |                 b.setvar('button', i))) | 
					
						
							|  |  |  |         field.bind('<Return>', | 
					
						
							|  |  |  |                lambda e, b=buttons[default], i=default: | 
					
						
							|  |  |  |                (b.flash(), | 
					
						
							|  |  |  |                 b.setvar('button', i))) | 
					
						
							| 
									
										
										
										
											1995-03-02 14:05:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     oldFocus = w.tk.call('focus') # XXX | 
					
						
							|  |  |  |     w.grab_set() | 
					
						
							|  |  |  |     field.focus() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # 5. Wait for the user to respond, then restore the focus | 
					
						
							|  |  |  |     # and return the index of the selected button. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     w.waitvar('button') | 
					
						
							|  |  |  |     v = field.get() | 
					
						
							|  |  |  |     w.destroy() | 
					
						
							|  |  |  |     w.tk.call('focus', oldFocus) # XXX | 
					
						
							|  |  |  |     if args: | 
					
						
							| 
									
										
										
										
											1998-04-10 19:15:27 +00:00
										 |  |  |         return v, w.getint(w.getvar('button')) | 
					
						
							| 
									
										
										
										
											1995-03-02 14:05:29 +00:00
										 |  |  |     else: | 
					
						
							| 
									
										
										
										
											1998-04-10 19:15:27 +00:00
										 |  |  |         return v | 
					
						
							| 
									
										
										
										
											1995-03-02 14:05:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def message(str): | 
					
						
							|  |  |  |     i = dialog(mainWidget, 'Message', str, '', 0, 'OK') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def askyn(str): | 
					
						
							|  |  |  |     i = dialog(mainWidget, 'Question', str, '', 0, 'No', 'Yes') | 
					
						
							|  |  |  |     return i | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def askync(str): | 
					
						
							|  |  |  |     i = dialog(mainWidget, 'Question', str, '', 0, 'Cancel', 'No', 'Yes') | 
					
						
							|  |  |  |     return i-1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def askstr(str): | 
					
						
							|  |  |  |     i = strdialog(mainWidget, 'Question', str, '', 0) | 
					
						
							|  |  |  |     return i | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-10 19:15:27 +00:00
										 |  |  | def askfile(str):       # XXXX For now... | 
					
						
							| 
									
										
										
										
											1995-03-02 14:05:29 +00:00
										 |  |  |     i = strdialog(mainWidget, 'Question', str, '', 0) | 
					
						
							|  |  |  |     return i | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  | # The rest is the test program. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def _go(): | 
					
						
							|  |  |  |     i = dialog(mainWidget, | 
					
						
							| 
									
										
										
										
											1998-04-10 19:15:27 +00:00
										 |  |  |                'Not Responding', | 
					
						
							|  |  |  |                "The file server isn't responding right now; " | 
					
						
							|  |  |  |                "I'll keep trying.", | 
					
						
							|  |  |  |                '', | 
					
						
							|  |  |  |                -1, | 
					
						
							|  |  |  |                'OK') | 
					
						
							| 
									
										
										
										
											1995-03-02 14:05:29 +00:00
										 |  |  |     print 'pressed button', i | 
					
						
							|  |  |  |     i = dialog(mainWidget, | 
					
						
							| 
									
										
										
										
											1998-04-10 19:15:27 +00:00
										 |  |  |                'File Modified', | 
					
						
							|  |  |  |                'File "tcl.h" has been modified since ' | 
					
						
							|  |  |  |                'the last time it was saved. ' | 
					
						
							|  |  |  |                'Do you want to save it before exiting the application?', | 
					
						
							|  |  |  |                'warning', | 
					
						
							|  |  |  |                0, | 
					
						
							|  |  |  |                'Save File', | 
					
						
							|  |  |  |                'Discard Changes', | 
					
						
							|  |  |  |                'Return To Editor') | 
					
						
							| 
									
										
										
										
											1995-03-02 14:05:29 +00:00
										 |  |  |     print 'pressed button', i | 
					
						
							|  |  |  |     print message('Test of message') | 
					
						
							|  |  |  |     print askyn('Test of yes/no') | 
					
						
							|  |  |  |     print askync('Test of yes/no/cancel') | 
					
						
							|  |  |  |     print askstr('Type a string:') | 
					
						
							|  |  |  |     print strdialog(mainWidget, 'Question', 'Another string:', '', | 
					
						
							| 
									
										
										
										
											1998-04-10 19:15:27 +00:00
										 |  |  |                   0, 'Save', 'Save as text') | 
					
						
							| 
									
										
										
										
											1995-03-02 14:05:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def _test(): | 
					
						
							|  |  |  |     import sys | 
					
						
							|  |  |  |     global mainWidget | 
					
						
							|  |  |  |     mainWidget = Frame() | 
					
						
							|  |  |  |     Pack.config(mainWidget) | 
					
						
							|  |  |  |     start = Button(mainWidget, | 
					
						
							| 
									
										
										
										
											1998-04-10 19:15:27 +00:00
										 |  |  |                    {'text': 'Press Here To Start', 'command': _go}) | 
					
						
							| 
									
										
										
										
											1995-03-02 14:05:29 +00:00
										 |  |  |     start.pack() | 
					
						
							|  |  |  |     endit = Button(mainWidget, | 
					
						
							| 
									
										
										
										
											1998-04-10 19:15:27 +00:00
										 |  |  |                    {'text': 'Exit', | 
					
						
							|  |  |  |                     'command': 'exit', | 
					
						
							|  |  |  |                     Pack: {'fill' : 'both'}}) | 
					
						
							| 
									
										
										
										
											1995-03-02 14:05:29 +00:00
										 |  |  |     mainWidget.mainloop() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if __name__ == '__main__': | 
					
						
							|  |  |  |     _test() |