Home | History | Annotate | Download | only in guido
      1 #! /usr/bin/env python
      2 
      3 # A Python function that generates dialog boxes with a text message,
      4 # optional bitmap, and any number of buttons.
      5 # Cf. Ousterhout, Tcl and the Tk Toolkit, Figs. 27.2-3, pp. 269-270.
      6 
      7 from Tkinter import *
      8 import sys
      9 
     10 
     11 def dialog(master, title, text, bitmap, default, *args):
     12 
     13     # 1. Create the top-level window and divide it into top
     14     # and bottom parts.
     15 
     16     w = Toplevel(master, class_='Dialog')
     17     w.title(title)
     18     w.iconname('Dialog')
     19 
     20     top = Frame(w, relief=RAISED, borderwidth=1)
     21     top.pack(side=TOP, fill=BOTH)
     22     bot = Frame(w, relief=RAISED, borderwidth=1)
     23     bot.pack(side=BOTTOM, fill=BOTH)
     24 
     25     # 2. Fill the top part with the bitmap and message.
     26 
     27     msg = Message(top, width='3i', text=text,
     28                   font='-Adobe-Times-Medium-R-Normal-*-180-*')
     29     msg.pack(side=RIGHT, expand=1, fill=BOTH, padx='3m', pady='3m')
     30     if bitmap:
     31         bm = Label(top, bitmap=bitmap)
     32         bm.pack(side=LEFT, padx='3m', pady='3m')
     33 
     34     # 3. Create a row of buttons at the bottom of the dialog.
     35 
     36     var = IntVar()
     37     buttons = []
     38     i = 0
     39     for but in args:
     40         b = Button(bot, text=but, command=lambda v=var,i=i: v.set(i))
     41         buttons.append(b)
     42         if i == default:
     43             bd = Frame(bot, relief=SUNKEN, borderwidth=1)
     44             bd.pack(side=LEFT, expand=1, padx='3m', pady='2m')
     45             b.lift()
     46             b.pack (in_=bd, side=LEFT,
     47                     padx='2m', pady='2m', ipadx='2m', ipady='1m')
     48         else:
     49             b.pack (side=LEFT, expand=1,
     50                     padx='3m', pady='3m', ipadx='2m', ipady='1m')
     51         i = i+1
     52 
     53     # 4. Set up a binding for <Return>, if there's a default,
     54     # set a grab, and claim the focus too.
     55 
     56     if default >= 0:
     57         w.bind('<Return>',
     58                lambda e, b=buttons[default], v=var, i=default:
     59                (b.flash(),
     60                 v.set(i)))
     61 
     62     oldFocus = w.focus_get()
     63     w.grab_set()
     64     w.focus_set()
     65 
     66     # 5. Wait for the user to respond, then restore the focus
     67     # and return the index of the selected button.
     68 
     69     w.waitvar(var)
     70     w.destroy()
     71     if oldFocus: oldFocus.focus_set()
     72     return var.get()
     73 
     74 # The rest is the test program.
     75 
     76 def go():
     77     i = dialog(mainWidget,
     78                'Not Responding',
     79                "The file server isn't responding right now; "
     80                "I'll keep trying.",
     81                '',
     82                -1,
     83                'OK')
     84     print 'pressed button', i
     85     i = dialog(mainWidget,
     86                'File Modified',
     87                'File "tcl.h" has been modified since '
     88                'the last time it was saved. '
     89                'Do you want to save it before exiting the application?',
     90                'warning',
     91                0,
     92                'Save File',
     93                'Discard Changes',
     94                'Return To Editor')
     95     print 'pressed button', i
     96 
     97 def test():
     98     import sys
     99     global mainWidget
    100     mainWidget = Frame()
    101     Pack.config(mainWidget)
    102     start = Button(mainWidget, text='Press Here To Start', command=go)
    103     start.pack()
    104     endit = Button(mainWidget, text="Exit", command=sys.exit)
    105     endit.pack(fill=BOTH)
    106     mainWidget.mainloop()
    107 
    108 if __name__ == '__main__':
    109     test()
    110