1 """
2 EasyGuiRevisionInfo = "version 0.83 2008-06-12"
3
4 EasyGui provides an easy-to-use interface for simple GUI interaction
5 with a user. It does not require the programmer to know anything about
6 tkinter, frames, widgets, callbacks or lambda. All GUI interactions are
7 invoked by simple function calls that return results.
8
9 Documentation is in an accompanying file, easygui.txt.
10
11 WARNING about using EasyGui with IDLE
12 =====================================
13
14 You may encounter problems using IDLE to run programs that use EasyGui. Try it
15 and find out. EasyGui is a collection of Tkinter routines that run their own
16 event loops. IDLE is also a Tkinter application, with its own event loop. The
17 two may conflict, with the unpredictable results. If you find that you have
18 problems, try running your program outside of IDLE.
19
20 Note that EasyGui requires Tk release 8.0 or greater.
21 """
22 EasyGuiRevisionInfo = "version 0.83 2008-06-12"
23
24
25
26 __all__ = ['ynbox'
27 , 'ccbox'
28 , 'boolbox'
29 , 'indexbox'
30 , 'msgbox'
31 , 'buttonbox'
32 , 'integerbox'
33 , 'multenterbox'
34 , 'enterbox'
35 , 'choicebox'
36 , 'codebox'
37 , 'textbox'
38 , 'diropenbox'
39 , 'fileopenbox'
40 , 'filesavebox'
41 , 'passwordbox'
42 , 'multpasswordbox'
43 , 'multchoicebox'
44 , 'abouteasygui'
45 ]
46
47 import sys, os
48 from Tkinter import *
49 if TkVersion < 8.0 :
50 print "\n" * 3
51 print "*"*75
52 print "Running Tk version:", TkVersion
53 print "You must be using Tk version 8.0 or greater to use EasyGui."
54 print "Terminating."
55 print "*"*75
56 print "\n" * 3
57 sys.exit(0)
58
59 -def dq(s): return '"%s"' % s
60
61 rootWindowPosition = "+300+200"
62 import string
63
64 DEFAULT_FONT_FAMILY = ("MS", "Sans", "Serif")
65 MONOSPACE_FONT_FAMILY = ("Courier")
66 DEFAULT_FONT_SIZE = 10
67 BIG_FONT_SIZE = 12
68 SMALL_FONT_SIZE = 9
69 CODEBOX_FONT_SIZE = 9
70 TEXTBOX_FONT_SIZE = DEFAULT_FONT_SIZE
71
72
73 import tkFileDialog
74
75
76
77
78
79
80
81
82 -def ynbox(msg="Shall I continue?", title=" ", choices=("Yes", "No"), image=None):
83 """
84 Display a msgbox with choices of Yes and No.
85
86 The default is "Yes".
87
88 The returned value is calculated this way::
89 if the first choice ("Yes") is chosen, or if the dialog is cancelled:
90 return 1
91 else:
92 return 0
93
94 If invoked without a msg argument, displays a generic request for a confirmation
95 that the user wishes to continue. So it can be used this way::
96 if ynbox(): pass # continue
97 else: sys.exit(0) # exit the program
98
99 @arg msg: the msg to be displayed.
100 @arg title: the window title
101 @arg choices: a list or tuple of the choices to be displayed
102 """
103 return boolbox(msg, title, choices, image=None)
104
105
106
107
108 -def ccbox(msg="Shall I continue?", title=" ",choices=("Continue", "Cancel"), image=None):
109 """
110 Display a msgbox with choices of Continue and Cancel.
111
112 The default is "Continue".
113
114 The returned value is calculated this way::
115 if the first choice ("Continue") is chosen, or if the dialog is cancelled:
116 return 1
117 else:
118 return 0
119
120 If invoked without a msg argument, displays a generic request for a confirmation
121 that the user wishes to continue. So it can be used this way::
122
123 if ccbox():
124 pass # continue
125 else:
126 sys.exit(0) # exit the program
127
128 @arg msg: the msg to be displayed.
129 @arg title: the window title
130 @arg choices: a list or tuple of the choices to be displayed
131 """
132 return boolbox(msg, title, choices, image=None)
133
134
135
136
137
138 -def boolbox(msg="Shall I continue?", title=" ", choices=("Yes","No"), image=None):
139 """
140 Display a boolean msgbox.
141
142 The default is the first choice.
143
144 The returned value is calculated this way::
145 if the first choice is chosen, or if the dialog is cancelled:
146 returns 1
147 else:
148 returns 0
149 """
150 reply = buttonbox(msg=msg, choices=choices, title=title, image=None)
151 if reply == choices[0]: return 1
152 else: return 0
153
154
155
156
157
158 -def indexbox(msg="Shall I continue?", title=" ", choices=("Yes","No"), image=None):
159 """
160 Display a buttonbox with the specified choices.
161 Return the index of the choice selected.
162 """
163 reply = buttonbox(msg=msg, choices=choices, title=title, image=None)
164 index = -1
165 for choice in choices:
166 index = index + 1
167 if reply == choice: return index
168 raise AssertionError("There is a program logic error in the EasyGui code for indexbox.")
169
170
171
172
173
174 -def msgbox(msg="(Your message goes here)", title=" ", buttons="OK",image=None):
175 """
176 Display a messagebox
177 """
178 if type(buttons) == type("abc"): pass
179 else: raise AssertionError("The 'buttons' argument to msgbox must be a string.")
180
181 return buttonbox(msg=msg, title=title, choices=[buttons], image=image)
182
183
184
185
186
256
257
258
259
260
261 -def integerbox(msg="", title=" ", default="", argLowerBound=0, argUpperBound=99):
262 """
263 Show a box in which a user can enter an integer.
264
265 In addition to arguments for msg and title, this function accepts
266 integer arguments for default_value, lowerbound, and upperbound.
267
268 The default_value argument may be None.
269
270 When the user enters some text, the text is checked to verify
271 that it can be converted to an integer between the lowerbound and upperbound.
272
273 If it can be, the integer (not the text) is returned.
274
275 If it cannot, then an error msg is displayed, and the integerbox is
276 redisplayed.
277
278 If the user cancels the operation, None is returned.
279 """
280 if default != "":
281 if type(default) != type(1):
282 raise AssertionError(
283 "integerbox received a non-integer value for "
284 + "default of " + dq(str(default)) , "Error")
285
286 if type(argLowerBound) != type(1):
287 raise AssertionError(
288 "integerbox received a non-integer value for "
289 + "argLowerBound of " + dq(str(argLowerBound)) , "Error")
290
291 if type(argUpperBound) != type(1):
292 raise AssertionError(
293 "integerbox received a non-integer value for "
294 + "argUpperBound of " + dq(str(argUpperBound)) , "Error")
295
296 if msg == "":
297 msg = ("Enter an integer between " + str(argLowerBound)
298 + " and "
299 + str(argUpperBound)
300 )
301
302 while 1:
303 reply = enterbox(msg, title, str(default))
304 if reply == None: return None
305
306 try:
307 reply = int(reply)
308 except:
309 msgbox ("The value that you entered:\n\t%s\nis not an integer." % dq(str(reply))
310 , "Error")
311 continue
312
313 if reply < argLowerBound:
314 msgbox ("The value that you entered is less than the lower bound of "
315 + str(argLowerBound) + ".", "Error")
316 continue
317
318 if reply > argUpperBound:
319 msgbox ("The value that you entered is greater than the upper bound of "
320 + str(argUpperBound) + ".", "Error")
321 continue
322
323
324
325 return reply
326
327
328
329
330 -def multenterbox(msg="Fill in values for the fields.", title=" "
331 , fields = (), values = () ):
332 """
333 Show screen with multiple data entry fields.
334
335 If there are fewer values than names, the list of values is padded with
336 empty strings until the number of values is the same as the number of names.
337
338 If there are more values than names, the list of values
339 is truncated so that there are as many values as names.
340
341 Returns a list of the values of the fields,
342 or None if the user cancels the operation.
343
344 Here is some example code, that shows how values returned from
345 multenterbox can be checked for validity before they are accepted::
346 ----------------------------------------------------------------------
347 msg = "Enter your personal information"
348 title = "Credit Card Application"
349 fieldNames = ["Name","Street Address","City","State","ZipCode"]
350 fieldValues = [] # we start with blanks for the values
351 fieldValues = multenterbox(msg,title, fieldNames)
352
353 # make sure that none of the fields was left blank
354 while 1:
355 if fieldValues == None: break
356 errmsg = ""
357 for i in range(len(fieldNames)):
358 if fieldValues[i].strip() == "":
359 errmsg = errmsg + ('"%s" is a required field.\n\n' % fieldNames[i])
360 if errmsg == "": break # no problems found
361 fieldValues = multenterbox(errmsg, title, fieldNames, fieldValues)
362
363 print "Reply was:", fieldValues
364 ----------------------------------------------------------------------
365
366 @arg msg: the msg to be displayed.
367 @arg title: the window title
368 @arg fields: a list of fieldnames.
369 @arg values: a list of field values
370 """
371 return __multfillablebox(msg,title,fields,values,None)
372
373
374
375
376
377 -def multpasswordbox(msg="Fill in values for the fields.", title=" "
378 , fields = (), values = () ):
379 """
380 Same interface as multenterbox. But in multpassword box,
381 the last of the fields is assumed to be a password, and
382 is masked with asterisks.
383
384 Here is some example code, that shows how values returned from
385 multpasswordbox can be checked for validity before they are accepted::
386 ----------------------------------------------------------------------
387 msg = "Enter logon information"
388 title = "Demo of multpasswordbox"
389 fieldNames = ["Server ID", "User ID", "Password"]
390 fieldValues = [] # we start with blanks for the values
391 fieldValues = multpasswordbox(msg,title, fieldNames)
392
393 # make sure that none of the fields was left blank
394 while 1:
395 if fieldValues == None: break
396 errmsg = ""
397 for i in range(len(fieldNames)):
398 if fieldValues[i].strip() == "":
399 errmsg = errmsg + ('"%s" is a required field.\n\n' % fieldNames[i])
400 if errmsg == "": break # no problems found
401 fieldValues = multpasswordbox(errmsg, title, fieldNames, fieldValues)
402
403 print "Reply was:", fieldValues
404 ----------------------------------------------------------------------
405 """
406 return __multfillablebox(msg,title,fields,values,"*")
407
408
409
410
411 -def __multfillablebox(msg="Fill in values for the fields.", title=" "
412 , fields=(), values=(), argMaskCharacter = None ):
413
414 global root, __multenterboxText, __multenterboxDefaultText, cancelButton, entryWidget, okButton
415
416 choices = ["OK", "Cancel"]
417 if len(fields) == 0: return None
418
419 fields = list(fields[:])
420 values = list(values[:])
421
422 if len(values) == len(fields): pass
423 elif len(values) > len(fields):
424 fields = fields[0:len(values)]
425 else:
426 while len(values) < len(fields):
427 values.append("")
428
429 root = Tk()
430 root.protocol('WM_DELETE_WINDOW', denyWindowManagerClose )
431 root.title(title)
432 root.iconname('Dialog')
433 root.geometry(rootWindowPosition)
434 root.bind("<Escape>", __multenterboxCancel)
435
436
437 messageFrame = Frame(root)
438 messageFrame.pack(side=TOP, fill=BOTH)
439
440
441 messageWidget = Message(messageFrame, width="4.5i", text=msg)
442 messageWidget.configure(font=(DEFAULT_FONT_FAMILY,DEFAULT_FONT_SIZE))
443 messageWidget.pack(side=RIGHT, expand=1, fill=BOTH, padx='3m', pady='3m')
444
445 global entryWidgets
446 entryWidgets = []
447
448 lastWidgetIndex = len(fields) - 1
449
450 for widgetIndex in range(len(fields)):
451 argFieldName = fields[widgetIndex]
452 argFieldValue = values[widgetIndex]
453 entryFrame = Frame(root)
454 entryFrame.pack(side=TOP, fill=BOTH)
455
456
457 labelWidget = Label(entryFrame, text=argFieldName)
458 labelWidget.pack(side=LEFT)
459
460 entryWidgets.append(Entry(entryFrame, width=40))
461 entryWidgets[widgetIndex].configure(font=(DEFAULT_FONT_FAMILY,BIG_FONT_SIZE))
462 entryWidgets[widgetIndex].pack(side=RIGHT, padx="3m")
463 entryWidgets[widgetIndex].bind("<Return>", __multenterboxGetText)
464 entryWidgets[widgetIndex].bind("<Escape>", __multenterboxCancel)
465
466
467
468 if widgetIndex == lastWidgetIndex:
469 if argMaskCharacter:
470 entryWidgets[widgetIndex].configure(show=argMaskCharacter)
471
472
473 entryWidgets[widgetIndex].insert(0,argFieldValue)
474 widgetIndex += 1
475
476
477
478 buttonsFrame = Frame(root)
479 buttonsFrame.pack(side=BOTTOM, fill=BOTH)
480
481
482 okButton = Button(buttonsFrame, takefocus=1, text="OK")
483 okButton.pack(expand=1, side=LEFT, padx='3m', pady='3m', ipadx='2m', ipady='1m')
484 okButton.bind("<Return>" , __multenterboxGetText)
485 okButton.bind("<Button-1>", __multenterboxGetText)
486
487
488 cancelButton = Button(buttonsFrame, takefocus=1, text="Cancel")
489 cancelButton.pack(expand=1, side=RIGHT, padx='3m', pady='3m', ipadx='2m', ipady='1m')
490 cancelButton.bind("<Return>" , __multenterboxCancel)
491 cancelButton.bind("<Button-1>", __multenterboxCancel)
492
493
494 entryWidgets[0].focus_force()
495 root.mainloop()
496
497
498 root.destroy()
499 return __multenterboxText
500
501
502
503
505 global root, __multenterboxText, entryWidget
506 __multenterboxText = []
507 global entryWidgets
508 for entryWidget in entryWidgets:
509 __multenterboxText.append(entryWidget.get())
510
511 root.quit()
512
514 global root, __multenterboxDefaultText, __multenterboxText
515 __multenterboxText = None
516
517 root.quit()
518
519
520
521
522
523 -def enterbox(msg="Enter something.", title=" ", default="",strip=True):
524 """
525 Show a box in which a user can enter some text.
526
527 You may optionally specify some default text, which will appear in the
528 enterbox when it is displayed.
529
530 Returns the text that the user entered, or None if he cancels the operation.
531
532 By default, enterbox strips its result (i.e. removes leading and trailing
533 whitespace). (If you want it not to strip, use keyword argument: strip=False.)
534 This makes it easier to test the results of the call::
535
536 reply = enterbox(....)
537 if reply:
538 ...
539 else:
540 ...
541 """
542 result = __fillablebox(msg, title, default=default, argMaskCharacter=None)
543 if result and strip:
544 result = result.strip()
545 return result
546
547
548 -def passwordbox(msg="Enter your password.", title=" ", default=""):
549 """
550 Show a box in which a user can enter a password.
551 The text is masked with asterisks, so the password is not displayed.
552 Returns the text that the user entered, or None if he cancels the operation.
553 """
554 return __fillablebox(msg, title, default, "*")
555
556
557 -def __fillablebox(msg, title="", default="", argMaskCharacter=None):
558 """
559 Show a box in which a user can enter some text.
560 You may optionally specify some default text, which will appear in the
561 enterbox when it is displayed.
562 Returns the text that the user entered, or None if he cancels the operation.
563 """
564
565 global root, __enterboxText, __enterboxDefaultText, cancelButton, entryWidget, okButton
566
567 if title == None: title == ""
568 if default == None: default = ""
569 __enterboxDefaultText = default
570 __enterboxText = __enterboxDefaultText
571 choices = ["OK", "Cancel"]
572
573 root = Tk()
574 root.protocol('WM_DELETE_WINDOW', denyWindowManagerClose )
575 root.title(title)
576 root.iconname('Dialog')
577 root.geometry(rootWindowPosition)
578 root.bind("<Escape>", __enterboxCancel)
579
580
581 messageFrame = Frame(root)
582 messageFrame.pack(side=TOP, fill=BOTH)
583
584 entryFrame = Frame(root)
585 entryFrame.pack(side=TOP, fill=BOTH)
586
587 buttonsFrame = Frame(root)
588 buttonsFrame.pack(side=BOTTOM, fill=BOTH)
589
590
591 messageWidget = Message(messageFrame, width="4.5i", text=msg)
592 messageWidget.configure(font=(DEFAULT_FONT_FAMILY,DEFAULT_FONT_SIZE))
593 messageWidget.pack(side=RIGHT, expand=1, fill=BOTH, padx='3m', pady='3m')
594
595
596 entryWidget = Entry(entryFrame, width=40)
597 entryWidget.configure(font=(DEFAULT_FONT_FAMILY,BIG_FONT_SIZE))
598 if argMaskCharacter:
599 entryWidget.configure(show=argMaskCharacter)
600 entryWidget.pack(side=LEFT, padx="3m")
601 entryWidget.bind("<Return>", __enterboxGetText)
602 entryWidget.bind("<Escape>", __enterboxCancel)
603
604 entryWidget.insert(0,__enterboxDefaultText)
605
606
607 okButton = Button(buttonsFrame, takefocus=1, text="OK")
608 okButton.pack(expand=1, side=LEFT, padx='3m', pady='3m', ipadx='2m', ipady='1m')
609 okButton.bind("<Return>" , __enterboxGetText)
610 okButton.bind("<Button-1>", __enterboxGetText)
611
612 ''' dead code ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
613 # ------------------ (possible) restore button -------------------------------
614 if default != None:
615 # make a button to restore the default text
616 restoreButton = Button(buttonsFrame, takefocus=1, text="Restore default")
617 restoreButton.pack(expand=1, side=LEFT, padx='3m', pady='3m', ipadx='2m', ipady='1m')
618 restoreButton.bind("<Return>" , __enterboxRestore)
619 restoreButton.bind("<Button-1>", __enterboxRestore)
620 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ dead code '''
621
622
623 cancelButton = Button(buttonsFrame, takefocus=1, text="Cancel")
624 cancelButton.pack(expand=1, side=RIGHT, padx='3m', pady='3m', ipadx='2m', ipady='1m')
625 cancelButton.bind("<Return>" , __enterboxCancel)
626 cancelButton.bind("<Button-1>", __enterboxCancel)
627
628
629 entryWidget.focus_force()
630 root.mainloop()
631
632
633 root.destroy()
634 return __enterboxText
635
636
637
639 global root, __enterboxText, entryWidget
640 __enterboxText = entryWidget.get()
641
642 root.quit()
643
645 global root, __enterboxText, entryWidget
646 entryWidget.delete(0,len(entryWidget.get()))
647 entryWidget.insert(0, __enterboxDefaultText)
648
650 global root, __enterboxDefaultText, __enterboxText
651 __enterboxText = None
652
653 root.quit()
654
656 """ don't allow WindowManager close
657 """
658 x = Tk()
659 x.withdraw()
660 x.bell()
661 x.destroy()
662
663
664
665
666
667
668 -def multchoicebox(msg="Pick as many items as you like.",title=" ",choices=(), **kwargs):
669 """
670 Present the user with a list of choices.
671 allow him to select multiple items and return them in a list.
672 if the user doesn't choose anything from the list, return the empty list.
673 return None if he cancelled selection.
674
675 @arg msg: the msg to be displayed.
676 @arg title: the window title
677 @arg choices: a list or tuple of the choices to be displayed
678 """
679 if len(choices) == 0: choices = ["Program logic error - no choices were specified."]
680
681 global __choiceboxMultipleSelect
682 __choiceboxMultipleSelect = 1
683 return __choicebox(msg, title, choices)
684
685
686
687
688
689 -def choicebox(msg="Pick something.",title=" ", choices=(), buttons=() ):
690 """
691 Present the user with a list of choices.
692 return the choice that he selects.
693 return None if he cancels the selection selection.
694
695 @arg msg: the msg to be displayed.
696 @arg title: the window title
697 @arg choices: a list or tuple of the choices to be displayed
698 """
699 if len(choices) == 0: choices = ["Program logic error - no choices were specified."]
700
701 global __choiceboxMultipleSelect
702 __choiceboxMultipleSelect = 0
703 return __choicebox(msg,title,choices,buttons)
704
705
706
707
708
710 """
711 internal routine to support choicebox() and multchoicebox()
712 """
713 global root, __choiceboxResults, choiceboxWidget, defaultText
714 global choiceboxWidget, choiceboxChoices
715
716
717
718
719
720
721 choices = list(choices[:])
722 if len(choices) == 0: choices = ["Program logic error - no choices were specified."]
723 defaultButtons = ["OK", "Cancel"]
724
725
726 for index in range(len(choices)):
727 choices[index] = str(choices[index])
728
729 if buttons:
730 if type(buttons) == type("abc"):
731 choiceboxButtons = [buttons]
732 else:
733 choiceboxButtons = buttons
734 else:
735 choiceboxButtons = defaultButtons
736
737 lines_to_show = min(len(choices), 20)
738 lines_to_show = 20
739
740 if title == None: title = ""
741
742
743
744 __choiceboxResults = None
745
746 root = Tk()
747 root.protocol('WM_DELETE_WINDOW', denyWindowManagerClose )
748 screen_width = root.winfo_screenwidth()
749 screen_height = root.winfo_screenheight()
750 root_width = int((screen_width * 0.8))
751 root_height = int((screen_height * 0.5))
752 root_xpos = int((screen_width * 0.1))
753 root_ypos = int((screen_height * 0.05))
754
755 root.title(title)
756 root.iconname('Dialog')
757 rootWindowPosition = "+0+0"
758 root.geometry(rootWindowPosition)
759 root.expand=NO
760 root.minsize(root_width, root_height)
761 rootWindowPosition = "+" + str(root_xpos) + "+" + str(root_ypos)
762 root.geometry(rootWindowPosition)
763
764
765 message_and_buttonsFrame = Frame(root)
766 message_and_buttonsFrame.pack(side=TOP, fill=X, expand=NO)
767
768 messageFrame = Frame(message_and_buttonsFrame)
769 messageFrame.pack(side=LEFT, fill=X, expand=YES)
770
771
772 buttonsFrame = Frame(message_and_buttonsFrame)
773 buttonsFrame.pack(side=RIGHT, expand=NO, pady=0)
774
775
776 choiceboxFrame = Frame(root)
777 choiceboxFrame.pack(side=BOTTOM, fill=BOTH, expand=YES)
778
779
780
781
782 messageWidget = Message(messageFrame, anchor=NW, text=msg, width=int(root_width * 0.9))
783 messageWidget.configure(font=(DEFAULT_FONT_FAMILY,DEFAULT_FONT_SIZE))
784 messageWidget.pack(side=LEFT, expand=YES, fill=BOTH, padx='1m', pady='1m')
785
786
787 choiceboxWidget = Listbox(choiceboxFrame
788 , height=lines_to_show
789 , borderwidth="1m"
790 , relief="flat"
791 , bg="white"
792 )
793
794 if __choiceboxMultipleSelect:
795 choiceboxWidget.configure(selectmode=MULTIPLE)
796
797 choiceboxWidget.configure(font=(DEFAULT_FONT_FAMILY,DEFAULT_FONT_SIZE))
798
799
800 rightScrollbar = Scrollbar(choiceboxFrame, orient=VERTICAL, command=choiceboxWidget.yview)
801 choiceboxWidget.configure(yscrollcommand = rightScrollbar.set)
802
803
804 bottomScrollbar = Scrollbar(choiceboxFrame, orient=HORIZONTAL, command=choiceboxWidget.xview)
805 choiceboxWidget.configure(xscrollcommand = bottomScrollbar.set)
806
807
808
809
810
811 bottomScrollbar.pack(side=BOTTOM, fill = X)
812 rightScrollbar.pack(side=RIGHT, fill = Y)
813
814 choiceboxWidget.pack(side=LEFT, padx="1m", pady="1m", expand=YES, fill=BOTH)
815
816
817
818
819
820
821 for index in range(len(choices)):
822 choices[index] == str(choices[index])
823
824 choices.sort( lambda x,y: cmp(x.lower(), y.lower()))
825 lastInserted = None
826 choiceboxChoices = []
827 for choice in choices:
828 if choice == lastInserted: pass
829 else:
830 choiceboxWidget.insert(END, choice)
831 choiceboxChoices.append(choice)
832 lastInserted = choice
833
834 root.bind('<Any-Key>', KeyboardListener)
835
836
837 if len(choices) > 0:
838 okButton = Button(buttonsFrame, takefocus=YES, text="OK", height=1, width=6)
839 okButton.pack(expand=NO, side=TOP, padx='2m', pady='1m', ipady="1m", ipadx="2m")
840 okButton.bind("<Return>", __choiceboxGetChoice)
841 okButton.bind("<Button-1>",__choiceboxGetChoice)
842
843
844 choiceboxWidget.bind("<Return>", __choiceboxGetChoice)
845 choiceboxWidget.bind("<Double-Button-1>", __choiceboxGetChoice)
846 else:
847
848 choiceboxWidget.bind("<Return>", __choiceboxCancel)
849 choiceboxWidget.bind("<Double-Button-1>", __choiceboxCancel)
850
851 cancelButton = Button(buttonsFrame, takefocus=YES, text="Cancel", height=1, width=6)
852 cancelButton.pack(expand=NO, side=BOTTOM, padx='2m', pady='1m', ipady="1m", ipadx="2m")
853 cancelButton.bind("<Return>", __choiceboxCancel)
854 cancelButton.bind("<Button-1>", __choiceboxCancel)
855
856
857 if len(choices) > 0 and __choiceboxMultipleSelect:
858 selectionButtonsFrame = Frame(messageFrame)
859 selectionButtonsFrame.pack(side=RIGHT, fill=Y, expand=NO)
860
861 selectAllButton = Button(selectionButtonsFrame, text="Select All", height=1, width=6)
862 selectAllButton.bind("<Button-1>",__choiceboxSelectAll)
863 selectAllButton.pack(expand=NO, side=TOP, padx='2m', pady='1m', ipady="1m", ipadx="2m")
864
865 clearAllButton = Button(selectionButtonsFrame, text="Clear All", height=1, width=6)
866 clearAllButton.bind("<Button-1>",__choiceboxClearAll)
867 clearAllButton.pack(expand=NO, side=TOP, padx='2m', pady='1m', ipady="1m", ipadx="2m")
868
869
870
871 root.bind("<Escape>", __choiceboxCancel)
872
873
874
875 choiceboxWidget.select_set(0)
876 choiceboxWidget.focus_force()
877
878
879 root.mainloop()
880
881 root.destroy()
882 return __choiceboxResults
883
884
886 global root, __choiceboxResults, choiceboxWidget
887
888 if __choiceboxMultipleSelect:
889 __choiceboxResults = [choiceboxWidget.get(index) for index in choiceboxWidget.curselection()]
890
891 else:
892 choice_index = choiceboxWidget.curselection()
893 __choiceboxResults = choiceboxWidget.get(choice_index)
894
895
896
897 root.quit()
898
899
901 global choiceboxWidget, choiceboxChoices
902 choiceboxWidget.selection_set(0, len(choiceboxChoices)-1)
903
905 global choiceboxWidget, choiceboxChoices
906 choiceboxWidget.selection_clear(0, len(choiceboxChoices)-1)
907
908
909
911 global root, __choiceboxResults
912
913 __choiceboxResults = None
914 root.quit()
915
916
918 global choiceboxChoices, choiceboxWidget
919 key = event.keysym
920 if len(key) <= 1:
921 if key in string.printable:
922
923
924 try:
925 start_n = int(choiceboxWidget.curselection()[0])
926 except IndexError:
927 start_n = -1
928
929
930 choiceboxWidget.selection_clear(0, 'end')
931
932
933 for n in range(start_n+1, len(choiceboxChoices)):
934 item = choiceboxChoices[n]
935 if item[0].lower() == key.lower():
936 choiceboxWidget.selection_set(first=n)
937 choiceboxWidget.see(n)
938 return
939 else:
940
941 for n in range(len(choiceboxChoices)):
942 item = choiceboxChoices[n]
943 if item[0].lower() == key.lower():
944 choiceboxWidget.selection_set(first = n)
945 choiceboxWidget.see(n)
946 return
947
948
949 for n in range(len(choiceboxChoices)):
950 item = choiceboxChoices[n]
951 if item[0].lower() > key.lower():
952 if n > 0:
953 choiceboxWidget.selection_set(first = (n-1))
954 else:
955 choiceboxWidget.selection_set(first = 0)
956 choiceboxWidget.see(n)
957 return
958
959
960
961 lastIndex = len(choiceboxChoices)-1
962 choiceboxWidget.selection_set(first = lastIndex)
963 choiceboxWidget.see(lastIndex)
964 return
965
966
967
968
969
970 -def codebox(msg="", title=" ", text=""):
971 """
972 Display some text in a monospaced font, with no line wrapping.
973 This function is suitable for displaying code and text that is
974 formatted using spaces.
975
976 The text parameter should be a string, or a list or tuple of lines to be
977 displayed in the textbox.
978 """
979 textbox(msg, title, text, codebox=1 )
980
981
982
983
984 -def textbox(msg="", title=" ", text="", codebox=0):
985 """
986 Display some text in a proportional font with line wrapping at word breaks.
987 This function is suitable for displaying general written text.
988
989 The text parameter should be a string, or a list or tuple of lines to be
990 displayed in the textbox.
991 """
992
993 if msg == None: msg = ""
994 if title == None: title = ""
995
996 global root, __replyButtonText, __widgetTexts, buttonsFrame
997 choices = ["0K"]
998 __replyButtonText = choices[0]
999
1000
1001 root = Tk()
1002
1003 root.protocol('WM_DELETE_WINDOW', denyWindowManagerClose )
1004
1005 screen_width = root.winfo_screenwidth()
1006 screen_height = root.winfo_screenheight()
1007 root_width = int((screen_width * 0.8))
1008 root_height = int((screen_height * 0.5))
1009 root_xpos = int((screen_width * 0.1))
1010 root_ypos = int((screen_height * 0.05))
1011
1012 root.title(title)
1013 root.iconname('Dialog')
1014 rootWindowPosition = "+0+0"
1015 root.geometry(rootWindowPosition)
1016 root.expand=NO
1017 root.minsize(root_width, root_height)
1018 rootWindowPosition = "+" + str(root_xpos) + "+" + str(root_ypos)
1019 root.geometry(rootWindowPosition)
1020
1021
1022 mainframe = Frame(root)
1023 mainframe.pack(side=TOP, fill=BOTH, expand=YES)
1024
1025
1026
1027 textboxFrame = Frame(mainframe, borderwidth=3)
1028 textboxFrame.pack(side=BOTTOM , fill=BOTH, expand=YES)
1029
1030 message_and_buttonsFrame = Frame(mainframe)
1031 message_and_buttonsFrame.pack(side=TOP, fill=X, expand=NO)
1032
1033 messageFrame = Frame(message_and_buttonsFrame)
1034 messageFrame.pack(side=LEFT, fill=X, expand=YES)
1035
1036 buttonsFrame = Frame(message_and_buttonsFrame)
1037 buttonsFrame.pack(side=RIGHT, expand=NO)
1038
1039
1040
1041
1042 if codebox:
1043 character_width = int((root_width * 0.6) / CODEBOX_FONT_SIZE)
1044 textbox = Text(textboxFrame,height=25,width=character_width, padx="2m", pady="1m")
1045 textbox.configure(wrap=NONE)
1046 textbox.configure(font=(MONOSPACE_FONT_FAMILY, CODEBOX_FONT_SIZE))
1047
1048 else:
1049 character_width = int((root_width * 0.6) / SMALL_FONT_SIZE)
1050 textbox = Text(
1051 textboxFrame
1052 , height=25
1053 , width=character_width
1054 , padx="2m"
1055 , pady="1m"
1056 )
1057 textbox.configure(wrap=WORD)
1058 textbox.configure(font=(DEFAULT_FONT_FAMILY,TEXTBOX_FONT_SIZE))
1059
1060
1061
1062 mainframe.bind("<Next>" , textbox.yview_scroll( 1,PAGES))
1063 mainframe.bind("<Prior>", textbox.yview_scroll(-1,PAGES))
1064
1065 mainframe.bind("<Right>", textbox.xview_scroll( 1,PAGES))
1066 mainframe.bind("<Left>" , textbox.xview_scroll(-1,PAGES))
1067
1068 mainframe.bind("<Down>", textbox.yview_scroll( 1,UNITS))
1069 mainframe.bind("<Up>" , textbox.yview_scroll(-1,UNITS))
1070
1071
1072
1073 rightScrollbar = Scrollbar(textboxFrame, orient=VERTICAL, command=textbox.yview)
1074 textbox.configure(yscrollcommand = rightScrollbar.set)
1075
1076
1077 bottomScrollbar = Scrollbar(textboxFrame, orient=HORIZONTAL, command=textbox.xview)
1078 textbox.configure(xscrollcommand = bottomScrollbar.set)
1079
1080
1081
1082
1083
1084
1085
1086
1087 if codebox:
1088 bottomScrollbar.pack(side=BOTTOM, fill=X)
1089 rightScrollbar.pack(side=RIGHT, fill=Y)
1090
1091 textbox.pack(side=LEFT, fill=BOTH, expand=YES)
1092
1093
1094
1095 messageWidget = Message(messageFrame, anchor=NW, text=msg, width=int(root_width * 0.9))
1096 messageWidget.configure(font=(DEFAULT_FONT_FAMILY,DEFAULT_FONT_SIZE))
1097 messageWidget.pack(side=LEFT, expand=YES, fill=BOTH, padx='1m', pady='1m')
1098
1099
1100 okButton = Button(buttonsFrame, takefocus=YES, text="OK", height=1, width=6)
1101 okButton.pack(expand=NO, side=TOP, padx='2m', pady='1m', ipady="1m", ipadx="2m")
1102 okButton.bind("<Return>" , __textboxOK)
1103 okButton.bind("<Button-1>", __textboxOK)
1104 okButton.bind("<Escape>" , __textboxOK)
1105
1106
1107
1108 try:
1109
1110 if type(text) == type("abc"): pass
1111 else:
1112 try:
1113 text = "".join(text)
1114 except:
1115 msgbox("Exception when trying to convert "+ str(type(text)) + " to text in textbox")
1116 sys.exit(16)
1117 textbox.insert(END,text, "normal")
1118
1119
1120 textbox.configure(state=DISABLED)
1121 except:
1122 msgbox("Exception when trying to load the textbox.")
1123 sys.exit(16)
1124
1125 try:
1126 okButton.focus_force()
1127 except:
1128 msgbox("Exception when trying to put focus on okButton.")
1129 sys.exit(16)
1130
1131 root.mainloop()
1132 root.destroy()
1133 return __replyButtonText
1134
1135
1136
1137
1138 -def __textboxOK(event):
1139 global root
1140
1141 root.quit()
1142
1143
1144
1145
1146
1147
1148 -def diropenbox(msg=None, title=None, default=None):
1149 """
1150 A dialog to get a directory name.
1151 Note that the msg argument, if specified, is ignored.
1152
1153 Returns the name of a directory, or None if user chose to cancel.
1154
1155 If the "default" argument specifies a directory name,
1156 and that directory exists,
1157 then the dialog box will start with that directory.
1158 """
1159 root = Tk()
1160 root.withdraw()
1161 if default == None:
1162 f = tkFileDialog.askdirectory(parent=root, title=title)
1163 else:
1164 f = tkFileDialog.askdirectory(parent=root, title=title, initialdir=default)
1165 if not f: return None
1166 return os.path.normpath(f)
1167
1168
1169
1170
1171
1173 """
1174 A dialog to get a file name.
1175 Returns the name of a file, or None if user chose to cancel.
1176
1177 If the "default" argument specifies a file name,
1178 then the dialog box will start with that file.
1179 """
1180 root = Tk()
1181 root.withdraw()
1182 f = tkFileDialog.askopenfilename(parent=root,title=title, initialfile=default)
1183 if not f: return None
1184 return os.path.normpath(f)
1185
1186
1187
1188
1189
1191 """
1192 A file to get the name of a file to save.
1193 Returns the name of a file, or None if user chose to cancel.
1194
1195 If the "default" argument specifies a file name,
1196 then the dialog box will start with that file.
1197 """
1198 root = Tk()
1199 root.withdraw()
1200 f = tkFileDialog.asksaveasfilename(parent=root, title=title, initialfile=default)
1201 if not f: return None
1202 return os.path.normpath(f)
1203
1204
1205
1206
1207
1208
1209
1217
1218
1242
1243
1244
1245
1246
1247
1248
1250
1251 print "\n" * 100
1252
1253 choices_abc = ["This is choice 1", "And this is choice 2"]
1254 msg = "Pick one! This is a huge choice, and you've got to make the right one " \
1255 "or you will surely mess up the rest of your life, and the lives of your " \
1256 "friends and neighbors!"
1257 title = ""
1258
1259
1260 code_snippet = ("dafsdfa dasflkj pp[oadsij asdfp;ij asdfpjkop asdfpok asdfpok asdfpok"*3) +"\n"+\
1261 """# here is some dummy Python code
1262 for someItem in myListOfStuff:
1263 do something(someItem)
1264 do something()
1265 do something()
1266 if somethingElse(someItem):
1267 doSomethingEvenMoreInteresting()
1268
1269 """*16
1270
1271
1272
1273 text_snippet = ((\
1274 """It was the best of times, and it was the worst of times. The rich ate cake, and the poor had cake recommended to them, but wished only for enough cash to buy bread. The time was ripe for revolution! """ \
1275 *5)+"\n\n")*10
1276
1277
1278
1279 intro_message = ("Pick the kind of box that you wish to demo.\n\n"
1280 + "In EasyGui, all GUI interactions are invoked by simple function calls.\n\n" +
1281 "EasyGui is different from other GUIs in that it is NOT event-driven. It allows" +
1282 " you to program in a traditional linear fashion, and to put up dialogs for simple" +
1283 " input and output when you need to. If you are new to the event-driven paradigm" +
1284 " for GUIs, EasyGui will allow you to be productive with very basic tasks" +
1285 " immediately. Later, if you wish to make the transition to an event-driven GUI" +
1286 " paradigm, you can move to an event-driven style with a more powerful GUI package" +
1287 "such as anygui, PythonCard, Tkinter, wxPython, etc."
1288 + "\n\nEasyGui is running Tk version: " + str(TkVersion)
1289 )
1290
1291
1292
1293
1294 while 1:
1295 choices = [
1296 "msgbox",
1297 "buttonbox",
1298 "buttonbox(image) -- an example of buttonbox with an 'image' specification",
1299 "choicebox",
1300 "multchoicebox",
1301 "textbox",
1302 "ynbox",
1303 "ccbox",
1304 "enterbox",
1305 "codebox",
1306 "integerbox",
1307 "boolbox",
1308 "indexbox",
1309 "filesavebox",
1310 "fileopenbox",
1311 "passwordbox",
1312 "multenterbox",
1313 "multpasswordbox",
1314 "diropenbox",
1315 "About EasyGui",
1316 " Help"
1317 ]
1318 choice = choicebox(msg=intro_message
1319 , title="EasyGui " + EasyGuiRevisionInfo
1320 , choices=choices)
1321
1322 if not choice: return
1323
1324 reply = choice.split()
1325
1326 if reply[0] == "msgbox":
1327 reply = msgbox("short msg", "This is a long title")
1328 print "Reply was:", repr(reply)
1329
1330 elif reply[0] == "About":
1331 reply = abouteasygui()
1332
1333 elif reply[0] == "Help":
1334 help("easygui")
1335
1336 elif reply[0] == "buttonbox":
1337 reply = buttonbox()
1338 print "Reply was:", repr(reply)
1339
1340 reply = buttonbox(msg=msg
1341 , title="Demo of Buttonbox with many, many buttons!"
1342 , choices=choices)
1343 print "Reply was:", repr(reply)
1344
1345 elif reply[0] == "buttonbox(image)":
1346 image = "python_and_check_logo.gif"
1347 msg = "Do you like this picture?"
1348 choices = ["Yes","No","No opinion"]
1349
1350 reply=buttonbox(msg,image=image,choices=choices)
1351 print "Reply was:", repr(reply)
1352
1353 image = os.path.normpath("python_and_check_logo.png")
1354 reply=buttonbox(msg,image=image, choices=choices)
1355 print "Reply was:", repr(reply)
1356
1357 image = os.path.normpath("zzzzz.gif")
1358 reply=buttonbox(msg,image=image, choices=choices)
1359 print "Reply was:", repr(reply)
1360
1361 elif reply[0] == "boolbox":
1362 reply = boolbox()
1363 print "Reply was:", repr(reply)
1364
1365 elif reply[0] == "enterbox":
1366 message = "Enter the name of your best friend."\
1367 "\n(Result will be stripped.)"
1368 reply = enterbox(message, "Love!", " Suzy Smith ")
1369 print "Reply was:", repr(reply)
1370
1371 message = "Enter the name of your best friend."\
1372 "\n(Result will NOT be stripped.)"
1373 reply = enterbox(message, "Love!", " Suzy Smith ",strip=False)
1374 print "Reply was:", repr(reply)
1375
1376 reply = enterbox("Enter the name of your worst enemy:", "Hate!")
1377 print "Reply was:", repr(reply)
1378
1379 elif reply[0] == "integerbox":
1380 reply = integerbox(
1381 "Enter a number between 3 and 333",
1382 "Demo: integerbox WITH a default value",
1383 222, 3, 333)
1384 print "Reply was:", repr(reply)
1385
1386 reply = integerbox(
1387 "Enter a number between 0 and 99",
1388 "Demo: integerbox WITHOUT a default value"
1389 )
1390 print "Reply was:", repr(reply)
1391
1392 elif reply[0] == "diropenbox":
1393 title = "Demo of diropenbox"
1394 msg = "This is a test of the diropenbox.\n\nPick the directory that you wish to open."
1395 d = diropenbox(msg, title)
1396 print "You chose directory...:", d
1397
1398 elif reply[0] == "fileopenbox":
1399 f = fileopenbox()
1400 print "You chose to open file:", f
1401
1402 elif reply[0] == "filesavebox":
1403 f = filesavebox()
1404 print "You chose to save file:", f
1405
1406 elif reply[0] == "indexbox":
1407 title = reply[0]
1408 msg = "Demo of " + reply[0]
1409 choices = ["Choice1", "Choice2", "Choice3", "Choice4"]
1410 reply = indexbox(msg, title, choices)
1411 print "Reply was:", repr(reply)
1412
1413 elif reply[0] == "passwordbox":
1414 reply = passwordbox("Demo of password box WITHOUT default"
1415 + "\n\nEnter your secret password", "Member Logon")
1416 print "Reply was:", str(reply)
1417
1418 reply = passwordbox("Demo of password box WITH default"
1419 + "\n\nEnter your secret password", "Member Logon", "alfie")
1420 print "Reply was:", str(reply)
1421
1422 elif reply[0] == "multenterbox":
1423 msg = "Enter your personal information"
1424 title = "Credit Card Application"
1425 fieldNames = ["Name","Street Address","City","State","ZipCode"]
1426 fieldValues = []
1427 fieldValues = multenterbox(msg,title, fieldNames)
1428
1429
1430 while 1:
1431 if fieldValues == None: break
1432 errmsg = ""
1433 for i in range(len(fieldNames)):
1434 if fieldValues[i].strip() == "":
1435 errmsg = errmsg + ('"%s" is a required field.\n\n' % fieldNames[i])
1436 if errmsg == "": break
1437 fieldValues = multenterbox(errmsg, title, fieldNames, fieldValues)
1438
1439 print "Reply was:", fieldValues
1440
1441 elif reply[0] == "multpasswordbox":
1442 msg = "Enter logon information"
1443 title = "Demo of multpasswordbox"
1444 fieldNames = ["Server ID", "User ID", "Password"]
1445 fieldValues = []
1446 fieldValues = multpasswordbox(msg,title, fieldNames)
1447
1448
1449 while 1:
1450 if fieldValues == None: break
1451 errmsg = ""
1452 for i in range(len(fieldNames)):
1453 if fieldValues[i].strip() == "":
1454 errmsg = errmsg + ('"%s" is a required field.\n\n' % fieldNames[i])
1455 if errmsg == "": break
1456 fieldValues = multpasswordbox(errmsg, title, fieldNames, fieldValues)
1457
1458 print "Reply was:", fieldValues
1459
1460
1461 elif reply[0] == "ynbox":
1462 reply = ynbox(msg, title)
1463 print "Reply was:", repr(reply)
1464
1465 elif reply[0] == "ccbox":
1466 reply = ccbox(msg)
1467 print "Reply was:", repr(reply)
1468
1469 elif reply[0] == "choicebox":
1470 longchoice = "This is an example of a very long option which you may or may not wish to choose."*2
1471 listChoices = ["nnn", "ddd", "eee", "fff", "aaa", longchoice
1472 , "aaa", "bbb", "ccc", "ggg", "hhh", "iii", "jjj", "kkk", "LLL", "mmm" , "nnn", "ooo", "ppp", "qqq", "rrr", "sss", "ttt", "uuu", "vvv"]
1473
1474 msg = "Pick something. " + ("A wrapable sentence of text ?! "*30) + "\nA separate line of text."*6
1475 reply = choicebox(msg=msg, choices=listChoices)
1476 print "Reply was:", repr(reply)
1477
1478 msg = "Pick something. "
1479 reply = choicebox(msg=msg, choices=listChoices)
1480 print "Reply was:", repr(reply)
1481
1482 msg = "Pick something. "
1483 reply = choicebox(msg="The list of choices is empty!", choices=[])
1484 print "Reply was:", repr(reply)
1485
1486 elif reply[0] == "multchoicebox":
1487 listChoices = ["aaa", "bbb", "ccc", "ggg", "hhh", "iii", "jjj", "kkk"
1488 , "LLL", "mmm" , "nnn", "ooo", "ppp", "qqq"
1489 , "rrr", "sss", "ttt", "uuu", "vvv"]
1490
1491 msg = "Pick as many choices as you wish."
1492 reply = multchoicebox(msg,"DEMO OF multchoicebox", listChoices)
1493 print "Reply was:", repr(reply)
1494
1495 elif reply[0] == "textbox":
1496 msg = "Here is some sample text. " * 16
1497 reply = textbox(msg, "Text Sample", text_snippet)
1498 print "Reply was:", repr(reply)
1499
1500 elif reply[0] == "codebox":
1501 msg = "Here is some sample code. " * 16
1502 reply = codebox(msg, "Code Sample", code_snippet)
1503 print "Reply was:", repr(reply)
1504
1505 else:
1506 msgbox("Choice\n\n" + choice + "\n\nis not recognized", "Program Logic Error")
1507 return
1508
1509 EASYGUI_ABOUT_INFORMATION = '''
1510 ========================================================================
1511 version 0.83 2008-06-12
1512 ========================================================================
1513
1514 BUG FIXES
1515 ------------------------------------------------------
1516 * fixed a bug in which fileopenbox, filesavebox, and diropenbox
1517 were returning an empty tuple, rather than None, when a user
1518 cancelled. Thanks to Nate Soares for reporting this and sending
1519 in a fix.
1520
1521 BACKWARD-INCOMPATIBLE CHANGES
1522 ------------------------------------------------------
1523 * changed enterbox so that by default it strips its result
1524 (i.e. removes leading and trailing whitespace).
1525 If you want it not to strip, use keyword argument: strip=False.
1526
1527 This change makes it easier to test the results of the call::
1528
1529 reply = enterbox(....)
1530 if reply:
1531 ...
1532 else:
1533 ...
1534
1535 * changed the name of the "button_text" (formerly "buttonMessage") parameter
1536 to "buttons" in the msgbox parameters.
1537
1538 ========================================================================
1539 version 0.80 2008-06-02
1540 ========================================================================
1541
1542 ENHANCEMENTS
1543 ------------------------------------------------------
1544 * added image keyword to msgbox and buttonbox
1545 Note that it can display only .gif images.
1546 see: http://effbot.org/tkinterbook/photoimage.htm
1547 * improved a lot of the docstrings.
1548 * added a new abouteasygui() function
1549
1550 BUG FIXES
1551 ------------------------------------------------------
1552 * changed mutable default arguments (lists) to tuples
1553
1554 * diropenbox, fileopenbox, and filesavebox now execute
1555 os.path.normpath() on the choice before returning it.
1556 This fixes a nasty bug/inconvenience for Windows users.
1557
1558 * In integerbox:
1559 old behavior: If user cancels, the default value is returned.
1560 new behavior: If user cancels, None is returned.
1561
1562 NOTE that this bugfix has the potential to break existing programs.
1563
1564
1565 CHANGES
1566 ------------------------------------------------------
1567 * removed the "restore default" button on enterbox.
1568 It was non-standard and was too long to display properly in
1569 some environments.
1570 * default message for buttonbox changed from
1571 "Shall I continue?" to just "".
1572
1573 BACKWARD-INCOMPATIBLE CHANGES
1574 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1575 These changes may break backward compatibility.
1576
1577 Note that the following changes may break backward compatibility
1578 in programs that invoke EasyGui functions with keyword
1579 (rather than positional) arguments.
1580
1581 They have been changed in order to standardize keyword arguments, so
1582 that EasyGui functions can be more easily used with keyword arguments.
1583 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1584 changed parameter name "message" to "msg" everywhere
1585 changed parameter name "buttonMessage" to "button_text"
1586 changed parameter name "argListOfFieldNames" to "fields"
1587 changed parameter name "argListOfFieldValues" to "values"
1588
1589 changed the following parameter names to "default":
1590 argDefault
1591 argDefaultPassword
1592 argDefaultText
1593 argInitialFile
1594 argInitialDir
1595 '''
1596
1603
1604
1605
1606 if __name__ == '__main__':
1607 _test()
1608