235 lines · 7.3 KB · Python
RawDownload
#! /usr/bin/env python # 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,                    Pack: {'side': 'top', 'fill': 'both'}})    bot = Frame(w, {'relief': 'raised', 'bd': 1,                    Pack: {'side': 'bottom', 'fill': 'both'}})     # 2. Fill the top part with the bitmap and message.     msg = Message(top,                  {'width': '3i',                   'text': text,                   'font': '-Adobe-Times-Medium-R-Normal-*-180-*',                   Pack: {'side': 'right', 'expand': 1,                          'fill': 'both',                          'padx': '3m', 'pady': '3m'}})    if bitmap:        bm = Label(top, {'bitmap': bitmap,                         Pack: {'side': 'left',                                'padx': '3m', 'pady': '3m'}})     # 3. Create a row of buttons at the bottom of the dialog.     buttons = []    i = 0    for but in args:        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     # 4. Set up a binding for <Return>, if there's a default,    # set a grab, and claim the focus too.     if default >= 0:        w.bind('<Return>',               lambda e, b=buttons[default], i=default:               (b.flash(),                b.setvar('button', i)))     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,                    Pack: {'side': 'top', 'fill': 'both'}})    if args:        bot = Frame(w, {'relief': 'raised', 'bd': 1,                    Pack: {'side': 'bottom', 'fill': 'both'}})     # 2. Fill the top part with the bitmap, message and input field.     if bitmap:        bm = Label(top, {'bitmap': bitmap,                         Pack: {'side': 'left',                                'padx': '3m', 'pady': '3m'}})     msg = Message(top,                  {'width': '3i',                   'text': text,                   'font': '-Adobe-Times-Medium-R-Normal-*-180-*',                   Pack: {'side': 'left',                          'fill': 'both',                          'padx': '3m', 'pady': '3m'}})     field = Entry(top,                  {'relief':'sunken',                   Pack:{'side':'left',                         'fill':'x',                         'expand':1,                         'padx':'3m', 'pady':'3m'}})    # 3. Create a row of buttons at the bottom of the dialog.     buttons = []    i = 0    for but in args:        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     # 4. Set up a binding for <Return>, if there's a default,    # set a grab, and claim the focus too.     if not args:        w.bind('<Return>', lambda arg, top=top: top.setvar('button', 0))        field.bind('<Return>', lambda arg, top=top: top.setvar('button', 0))    elif default >= 0:        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)))     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:        return v, w.getint(w.getvar('button'))    else:        return v 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 def askfile(str):       # XXXX For now...    i = strdialog(mainWidget, 'Question', str, '', 0)    return i # The rest is the test program. def _go():    i = dialog(mainWidget,               'Not Responding',               "The file server isn't responding right now; "               "I'll keep trying.",               '',               -1,               'OK')    print 'pressed button', i    i = dialog(mainWidget,               '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')    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:', '',                  0, 'Save', 'Save as text') def _test():    import sys    global mainWidget    mainWidget = Frame()    Pack.config(mainWidget)    start = Button(mainWidget,                   {'text': 'Press Here To Start', 'command': _go})    start.pack()    endit = Button(mainWidget,                   {'text': 'Exit',                    'command': 'exit',                    Pack: {'fill' : 'both'}})    mainWidget.mainloop() if __name__ == '__main__':    _test()