Home | History | Annotate | Download | only in tix
      1 # -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
      2 #
      3 # $Id$
      4 #
      5 # tixwidgets.py --
      6 #
      7 #       For Tix, see http://tix.sourceforge.net
      8 #
      9 #       This is a demo program of some of the Tix widgets available in Python.
     10 #       If you have installed Python & Tix properly, you can execute this as
     11 #
     12 #               % python tixwidgets.py
     13 #
     14 
     15 import os, os.path, sys, Tix
     16 from Tkconstants import *
     17 import traceback, tkMessageBox
     18 
     19 TCL_DONT_WAIT           = 1<<1
     20 TCL_WINDOW_EVENTS       = 1<<2
     21 TCL_FILE_EVENTS         = 1<<3
     22 TCL_TIMER_EVENTS        = 1<<4
     23 TCL_IDLE_EVENTS         = 1<<5
     24 TCL_ALL_EVENTS          = 0
     25 
     26 class Demo:
     27     def __init__(self, top):
     28         self.root = top
     29         self.exit = -1
     30 
     31         self.dir = None                         # script directory
     32         self.balloon = None                     # balloon widget
     33         self.useBalloons = Tix.StringVar()
     34         self.useBalloons.set('0')
     35         self.statusbar = None                   # status bar widget
     36         self.welmsg = None                      # Msg widget
     37         self.welfont = ''                       # font name
     38         self.welsize = ''                       # font size
     39 
     40         progname = sys.argv[0]
     41         dirname = os.path.dirname(progname)
     42         if dirname and dirname != os.curdir:
     43             self.dir = dirname
     44             index = -1
     45             for i in range(len(sys.path)):
     46                 p = sys.path[i]
     47                 if p in ("", os.curdir):
     48                     index = i
     49             if index >= 0:
     50                 sys.path[index] = dirname
     51             else:
     52                 sys.path.insert(0, dirname)
     53         else:
     54             self.dir = os.getcwd()
     55         sys.path.insert(0, self.dir+'/samples')
     56 
     57     def MkMainMenu(self):
     58         top = self.root
     59         w = Tix.Frame(top, bd=2, relief=RAISED)
     60         file = Tix.Menubutton(w, text='File', underline=0, takefocus=0)
     61         help = Tix.Menubutton(w, text='Help', underline=0, takefocus=0)
     62         file.pack(side=LEFT)
     63         help.pack(side=RIGHT)
     64         fm = Tix.Menu(file, tearoff=0)
     65         file['menu'] = fm
     66         hm = Tix.Menu(help, tearoff=0)
     67         help['menu'] = hm
     68 
     69         fm.add_command(label='Exit', underline=1,
     70                      command = lambda self=self: self.quitcmd () )
     71         hm.add_checkbutton(label='BalloonHelp', underline=0, command=ToggleHelp,
     72                            variable=self.useBalloons)
     73         # The trace variable option doesn't seem to work, instead I use 'command'
     74         #apply(w.tk.call, ('trace', 'variable', self.useBalloons, 'w',
     75         #                     ToggleHelp))
     76 
     77         return w
     78 
     79     def MkMainNotebook(self):
     80         top = self.root
     81         w = Tix.NoteBook(top, ipadx=5, ipady=5, options="""
     82         tagPadX 6
     83         tagPadY 4
     84         borderWidth 2
     85         """)
     86         # This may be required if there is no *Background option
     87         top['bg'] = w['bg']
     88 
     89         w.add('wel', label='Welcome', underline=0,
     90               createcmd=lambda w=w, name='wel': MkWelcome(w, name))
     91         w.add('cho', label='Choosers', underline=0,
     92               createcmd=lambda w=w, name='cho': MkChoosers(w, name))
     93         w.add('scr', label='Scrolled Widgets', underline=0,
     94               createcmd=lambda w=w, name='scr': MkScroll(w, name))
     95         w.add('mgr', label='Manager Widgets', underline=0,
     96               createcmd=lambda w=w, name='mgr': MkManager(w, name))
     97         w.add('dir', label='Directory List', underline=0,
     98               createcmd=lambda w=w, name='dir': MkDirList(w, name))
     99         w.add('exp', label='Run Sample Programs', underline=0,
    100               createcmd=lambda w=w, name='exp': MkSample(w, name))
    101         return w
    102 
    103     def MkMainStatus(self):
    104         global demo
    105         top = self.root
    106 
    107         w = Tix.Frame(top, relief=Tix.RAISED, bd=1)
    108         demo.statusbar = Tix.Label(w, relief=Tix.SUNKEN, bd=1)
    109         demo.statusbar.form(padx=3, pady=3, left=0, right='%70')
    110         return w
    111 
    112     def build(self):
    113         root = self.root
    114         z = root.winfo_toplevel()
    115         z.wm_title('Tix Widget Demonstration')
    116         if z.winfo_screenwidth() <= 800:
    117             z.geometry('790x590+10+10')
    118         else:
    119             z.geometry('890x640+10+10')
    120         demo.balloon = Tix.Balloon(root)
    121         frame1 = self.MkMainMenu()
    122         frame2 = self.MkMainNotebook()
    123         frame3 = self.MkMainStatus()
    124         frame1.pack(side=TOP, fill=X)
    125         frame3.pack(side=BOTTOM, fill=X)
    126         frame2.pack(side=TOP, expand=1, fill=BOTH, padx=4, pady=4)
    127         demo.balloon['statusbar'] = demo.statusbar
    128         z.wm_protocol("WM_DELETE_WINDOW", lambda self=self: self.quitcmd())
    129 
    130         # To show Tcl errors - uncomment this to see the listbox bug.
    131         # Tkinter defines a Tcl tkerror procedure that in effect
    132         # silences all background Tcl error reporting.
    133         # root.tk.eval('if {[info commands tkerror] != ""} {rename tkerror pytkerror}')
    134     def quitcmd (self):
    135         """Quit our mainloop. It is up to you to call root.destroy() after."""
    136         self.exit = 0
    137 
    138     def loop(self):
    139         """This is an explict replacement for _tkinter mainloop()
    140         It lets you catch keyboard interrupts easier, and avoids
    141         the 20 msec. dead sleep() which burns a constant CPU."""
    142         while self.exit < 0:
    143             # There are 2 whiles here. The outer one lets you continue
    144             # after a ^C interrupt.
    145             try:
    146                 # This is the replacement for _tkinter mainloop()
    147                 # It blocks waiting for the next Tcl event using select.
    148                 while self.exit < 0:
    149                     self.root.tk.dooneevent(TCL_ALL_EVENTS)
    150             except SystemExit:
    151                 # Tkinter uses SystemExit to exit
    152                 #print 'Exit'
    153                 self.exit = 1
    154                 return
    155             except KeyboardInterrupt:
    156                 if tkMessageBox.askquestion ('Interrupt', 'Really Quit?') == 'yes':
    157                     # self.tk.eval('exit')
    158                     self.exit = 1
    159                     return
    160                 continue
    161             except:
    162                 # Otherwise it's some other error - be nice and say why
    163                 t, v, tb = sys.exc_info()
    164                 text = ""
    165                 for line in traceback.format_exception(t,v,tb):
    166                     text += line + '\n'
    167                 try: tkMessageBox.showerror ('Error', text)
    168                 except: pass
    169                 self.exit = 1
    170                 raise SystemExit, 1
    171 
    172     def destroy (self):
    173         self.root.destroy()
    174 
    175 def RunMain(root):
    176     global demo
    177 
    178     demo = Demo(root)
    179 
    180     demo.build()
    181     demo.loop()
    182     demo.destroy()
    183 
    184 # Tabs
    185 def MkWelcome(nb, name):
    186     w = nb.page(name)
    187     bar = MkWelcomeBar(w)
    188     text = MkWelcomeText(w)
    189     bar.pack(side=TOP, fill=X, padx=2, pady=2)
    190     text.pack(side=TOP, fill=BOTH, expand=1)
    191 
    192 def MkWelcomeBar(top):
    193     global demo
    194 
    195     w = Tix.Frame(top, bd=2, relief=Tix.GROOVE)
    196     b1 = Tix.ComboBox(w, command=lambda w=top: MainTextFont(w))
    197     b2 = Tix.ComboBox(w, command=lambda w=top: MainTextFont(w))
    198     b1.entry['width'] = 15
    199     b1.slistbox.listbox['height'] = 3
    200     b2.entry['width'] = 4
    201     b2.slistbox.listbox['height'] = 3
    202 
    203     demo.welfont = b1
    204     demo.welsize = b2
    205 
    206     b1.insert(Tix.END, 'Courier')
    207     b1.insert(Tix.END, 'Helvetica')
    208     b1.insert(Tix.END, 'Lucida')
    209     b1.insert(Tix.END, 'Times Roman')
    210 
    211     b2.insert(Tix.END, '8')
    212     b2.insert(Tix.END, '10')
    213     b2.insert(Tix.END, '12')
    214     b2.insert(Tix.END, '14')
    215     b2.insert(Tix.END, '18')
    216 
    217     b1.pick(1)
    218     b2.pick(3)
    219 
    220     b1.pack(side=Tix.LEFT, padx=4, pady=4)
    221     b2.pack(side=Tix.LEFT, padx=4, pady=4)
    222 
    223     demo.balloon.bind_widget(b1, msg='Choose\na font',
    224                              statusmsg='Choose a font for this page')
    225     demo.balloon.bind_widget(b2, msg='Point size',
    226                              statusmsg='Choose the font size for this page')
    227     return w
    228 
    229 def MkWelcomeText(top):
    230     global demo
    231 
    232     w = Tix.ScrolledWindow(top, scrollbar='auto')
    233     win = w.window
    234     text = 'Welcome to TIX in Python'
    235     title = Tix.Label(win,
    236                       bd=0, width=30, anchor=Tix.N, text=text)
    237     msg = Tix.Message(win,
    238                       bd=0, width=400, anchor=Tix.N,
    239                       text='Tix is a set of mega-widgets based on TK. This program \
    240 demonstrates the widgets in the Tix widget set. You can choose the pages \
    241 in this window to look at the corresponding widgets. \n\n\
    242 To quit this program, choose the "File | Exit" command.\n\n\
    243 For more information, see http://tix.sourceforge.net.')
    244     title.pack(expand=1, fill=Tix.BOTH, padx=10, pady=10)
    245     msg.pack(expand=1, fill=Tix.BOTH, padx=10, pady=10)
    246     demo.welmsg = msg
    247     return w
    248 
    249 def MainTextFont(w):
    250     global demo
    251 
    252     if not demo.welmsg:
    253         return
    254     font = demo.welfont['value']
    255     point = demo.welsize['value']
    256     if font == 'Times Roman':
    257         font = 'times'
    258     fontstr = '%s %s' % (font, point)
    259     demo.welmsg['font'] = fontstr
    260 
    261 def ToggleHelp():
    262     if demo.useBalloons.get() == '1':
    263         demo.balloon['state'] = 'both'
    264     else:
    265         demo.balloon['state'] = 'none'
    266 
    267 def MkChoosers(nb, name):
    268     w = nb.page(name)
    269     options = "label.padX 4"
    270 
    271     til = Tix.LabelFrame(w, label='Chooser Widgets', options=options)
    272     cbx = Tix.LabelFrame(w, label='tixComboBox', options=options)
    273     ctl = Tix.LabelFrame(w, label='tixControl', options=options)
    274     sel = Tix.LabelFrame(w, label='tixSelect', options=options)
    275     opt = Tix.LabelFrame(w, label='tixOptionMenu', options=options)
    276     fil = Tix.LabelFrame(w, label='tixFileEntry', options=options)
    277     fbx = Tix.LabelFrame(w, label='tixFileSelectBox', options=options)
    278     tbr = Tix.LabelFrame(w, label='Tool Bar', options=options)
    279 
    280     MkTitle(til.frame)
    281     MkCombo(cbx.frame)
    282     MkControl(ctl.frame)
    283     MkSelect(sel.frame)
    284     MkOptMenu(opt.frame)
    285     MkFileEnt(fil.frame)
    286     MkFileBox(fbx.frame)
    287     MkToolBar(tbr.frame)
    288 
    289     # First column: comBox and selector
    290     cbx.form(top=0, left=0, right='%33')
    291     sel.form(left=0, right='&'+str(cbx), top=cbx)
    292     opt.form(left=0, right='&'+str(cbx), top=sel, bottom=-1)
    293 
    294     # Second column: title .. etc
    295     til.form(left=cbx, top=0,right='%66')
    296     ctl.form(left=cbx, right='&'+str(til), top=til)
    297     fil.form(left=cbx, right='&'+str(til), top=ctl)
    298     tbr.form(left=cbx, right='&'+str(til), top=fil, bottom=-1)
    299 
    300     #
    301     # Third column: file selection
    302     fbx.form(right=-1, top=0, left='%66')
    303 
    304 def MkCombo(w):
    305     options="label.width %d label.anchor %s entry.width %d" % (10, Tix.E, 14)
    306 
    307     static = Tix.ComboBox(w, label='Static', editable=0, options=options)
    308     editable = Tix.ComboBox(w, label='Editable', editable=1, options=options)
    309     history = Tix.ComboBox(w, label='History', editable=1, history=1,
    310                            anchor=Tix.E, options=options)
    311     static.insert(Tix.END, 'January')
    312     static.insert(Tix.END, 'February')
    313     static.insert(Tix.END, 'March')
    314     static.insert(Tix.END, 'April')
    315     static.insert(Tix.END, 'May')
    316     static.insert(Tix.END, 'June')
    317     static.insert(Tix.END, 'July')
    318     static.insert(Tix.END, 'August')
    319     static.insert(Tix.END, 'September')
    320     static.insert(Tix.END, 'October')
    321     static.insert(Tix.END, 'November')
    322     static.insert(Tix.END, 'December')
    323 
    324     editable.insert(Tix.END, 'Angola')
    325     editable.insert(Tix.END, 'Bangladesh')
    326     editable.insert(Tix.END, 'China')
    327     editable.insert(Tix.END, 'Denmark')
    328     editable.insert(Tix.END, 'Ecuador')
    329 
    330     history.insert(Tix.END, '/usr/bin/ksh')
    331     history.insert(Tix.END, '/usr/local/lib/python')
    332     history.insert(Tix.END, '/var/adm')
    333 
    334     static.pack(side=Tix.TOP, padx=5, pady=3)
    335     editable.pack(side=Tix.TOP, padx=5, pady=3)
    336     history.pack(side=Tix.TOP, padx=5, pady=3)
    337 
    338 states = ['Bengal', 'Delhi', 'Karnataka', 'Tamil Nadu']
    339 
    340 def spin_cmd(w, inc):
    341     idx = states.index(demo_spintxt.get()) + inc
    342     if idx < 0:
    343         idx = len(states) - 1
    344     elif idx >= len(states):
    345         idx = 0
    346 # following doesn't work.
    347 #    return states[idx]
    348     demo_spintxt.set(states[idx])       # this works
    349 
    350 def spin_validate(w):
    351     global states, demo_spintxt
    352 
    353     try:
    354         i = states.index(demo_spintxt.get())
    355     except ValueError:
    356         return states[0]
    357     return states[i]
    358     # why this procedure works as opposed to the previous one beats me.
    359 
    360 def MkControl(w):
    361     global demo_spintxt
    362 
    363     options="label.width %d label.anchor %s entry.width %d" % (10, Tix.E, 13)
    364 
    365     demo_spintxt = Tix.StringVar()
    366     demo_spintxt.set(states[0])
    367     simple = Tix.Control(w, label='Numbers', options=options)
    368     spintxt = Tix.Control(w, label='States', variable=demo_spintxt,
    369                           options=options)
    370     spintxt['incrcmd'] = lambda w=spintxt: spin_cmd(w, 1)
    371     spintxt['decrcmd'] = lambda w=spintxt: spin_cmd(w, -1)
    372     spintxt['validatecmd'] = lambda w=spintxt: spin_validate(w)
    373 
    374     simple.pack(side=Tix.TOP, padx=5, pady=3)
    375     spintxt.pack(side=Tix.TOP, padx=5, pady=3)
    376 
    377 def MkSelect(w):
    378     options = "label.anchor %s" % Tix.CENTER
    379 
    380     sel1 = Tix.Select(w, label='Mere Mortals', allowzero=1, radio=1,
    381                       orientation=Tix.VERTICAL,
    382                       labelside=Tix.TOP,
    383                       options=options)
    384     sel2 = Tix.Select(w, label='Geeks', allowzero=1, radio=0,
    385                       orientation=Tix.VERTICAL,
    386                       labelside= Tix.TOP,
    387                       options=options)
    388 
    389     sel1.add('eat', text='Eat')
    390     sel1.add('work', text='Work')
    391     sel1.add('play', text='Play')
    392     sel1.add('party', text='Party')
    393     sel1.add('sleep', text='Sleep')
    394 
    395     sel2.add('eat', text='Eat')
    396     sel2.add('prog1', text='Program')
    397     sel2.add('prog2', text='Program')
    398     sel2.add('prog3', text='Program')
    399     sel2.add('sleep', text='Sleep')
    400 
    401     sel1.pack(side=Tix.LEFT, padx=5, pady=3, fill=Tix.X)
    402     sel2.pack(side=Tix.LEFT, padx=5, pady=3, fill=Tix.X)
    403 
    404 def MkOptMenu(w):
    405     options='menubutton.width 15 label.anchor %s' % Tix.E
    406 
    407     m = Tix.OptionMenu(w, label='File Format : ', options=options)
    408     m.add_command('text', label='Plain Text')
    409     m.add_command('post', label='PostScript')
    410     m.add_command('format', label='Formatted Text')
    411     m.add_command('html', label='HTML')
    412     m.add_command('sep')
    413     m.add_command('tex', label='LaTeX')
    414     m.add_command('rtf', label='Rich Text Format')
    415 
    416     m.pack(fill=Tix.X, padx=5, pady=3)
    417 
    418 def MkFileEnt(w):
    419     msg = Tix.Message(w,
    420                       relief=Tix.FLAT, width=240, anchor=Tix.N,
    421                       text='Press the "open file" icon button and a TixFileSelectDialog will popup.')
    422     ent = Tix.FileEntry(w, label='Select a file : ')
    423     msg.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH, padx=3, pady=3)
    424     ent.pack(side=Tix.TOP, fill=Tix.X, padx=3, pady=3)
    425 
    426 def MkFileBox(w):
    427     """The FileSelectBox is a Motif-style box with various enhancements.
    428     For example, you can adjust the size of the two listboxes
    429     and your past selections are recorded.
    430     """
    431     msg = Tix.Message(w,
    432                       relief=Tix.FLAT, width=240, anchor=Tix.N,
    433                       text='The Tix FileSelectBox is a Motif-style box with various enhancements. For example, you can adjust the size of the two listboxes and your past selections are recorded.')
    434     box = Tix.FileSelectBox(w)
    435     msg.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH, padx=3, pady=3)
    436     box.pack(side=Tix.TOP, fill=Tix.X, padx=3, pady=3)
    437 
    438 def MkToolBar(w):
    439     """The Select widget is also good for arranging buttons in a tool bar.
    440     """
    441     global demo
    442 
    443     options='frame.borderWidth 1'
    444 
    445     msg = Tix.Message(w,
    446                       relief=Tix.FLAT, width=240, anchor=Tix.N,
    447                       text='The Select widget is also good for arranging buttons in a tool bar.')
    448     bar = Tix.Frame(w, bd=2, relief=Tix.RAISED)
    449     font = Tix.Select(w, allowzero=1, radio=0, label='', options=options)
    450     para = Tix.Select(w, allowzero=0, radio=1, label='', options=options)
    451 
    452     font.add('bold', bitmap='@' + demo.dir + '/bitmaps/bold.xbm')
    453     font.add('italic', bitmap='@' + demo.dir + '/bitmaps/italic.xbm')
    454     font.add('underline', bitmap='@' + demo.dir + '/bitmaps/underline.xbm')
    455     font.add('capital', bitmap='@' + demo.dir + '/bitmaps/capital.xbm')
    456 
    457     para.add('left', bitmap='@' + demo.dir + '/bitmaps/leftj.xbm')
    458     para.add('right', bitmap='@' + demo.dir + '/bitmaps/rightj.xbm')
    459     para.add('center', bitmap='@' + demo.dir + '/bitmaps/centerj.xbm')
    460     para.add('justify', bitmap='@' + demo.dir + '/bitmaps/justify.xbm')
    461 
    462     msg.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH, padx=3, pady=3)
    463     bar.pack(side=Tix.TOP, fill=Tix.X, padx=3, pady=3)
    464     font.pack({'in':bar}, side=Tix.LEFT, padx=3, pady=3)
    465     para.pack({'in':bar}, side=Tix.LEFT, padx=3, pady=3)
    466 
    467 def MkTitle(w):
    468     msg = Tix.Message(w,
    469                       relief=Tix.FLAT, width=240, anchor=Tix.N,
    470                       text='There are many types of "chooser" widgets that allow the user to input different types of information')
    471     msg.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH, padx=3, pady=3)
    472 
    473 def MkScroll(nb, name):
    474     w = nb.page(name)
    475     options='label.padX 4'
    476 
    477     sls = Tix.LabelFrame(w, label='Tix.ScrolledListBox', options=options)
    478     swn = Tix.LabelFrame(w, label='Tix.ScrolledWindow', options=options)
    479     stx = Tix.LabelFrame(w, label='Tix.ScrolledText', options=options)
    480 
    481     MkSList(sls.frame)
    482     MkSWindow(swn.frame)
    483     MkSText(stx.frame)
    484 
    485     sls.form(top=0, left=0, right='%33', bottom=-1)
    486     swn.form(top=0, left=sls, right='%66', bottom=-1)
    487     stx.form(top=0, left=swn, right=-1, bottom=-1)
    488 
    489 
    490 def MkSList(w):
    491     """This TixScrolledListBox is configured so that it uses scrollbars
    492     only when it is necessary. Use the handles to resize the listbox and
    493     watch the scrollbars automatically appear and disappear.  """
    494     top = Tix.Frame(w, width=300, height=330)
    495     bot = Tix.Frame(w)
    496     msg = Tix.Message(top,
    497                       relief=Tix.FLAT, width=200, anchor=Tix.N,
    498                       text='This TixScrolledListBox is configured so that it uses scrollbars only when it is necessary. Use the handles to resize the listbox and watch the scrollbars automatically appear and disappear.')
    499 
    500     list = Tix.ScrolledListBox(top, scrollbar='auto')
    501     list.place(x=50, y=150, width=120, height=80)
    502     list.listbox.insert(Tix.END, 'Alabama')
    503     list.listbox.insert(Tix.END, 'California')
    504     list.listbox.insert(Tix.END, 'Montana')
    505     list.listbox.insert(Tix.END, 'New Jersey')
    506     list.listbox.insert(Tix.END, 'New York')
    507     list.listbox.insert(Tix.END, 'Pennsylvania')
    508     list.listbox.insert(Tix.END, 'Washington')
    509 
    510     rh = Tix.ResizeHandle(top, bg='black',
    511                           relief=Tix.RAISED,
    512                           handlesize=8, gridded=1, minwidth=50, minheight=30)
    513     btn = Tix.Button(bot, text='Reset', command=lambda w=rh, x=list: SList_reset(w,x))
    514     top.propagate(0)
    515     msg.pack(fill=Tix.X)
    516     btn.pack(anchor=Tix.CENTER)
    517     top.pack(expand=1, fill=Tix.BOTH)
    518     bot.pack(fill=Tix.BOTH)
    519     list.bind('<Map>', func=lambda arg=0, rh=rh, list=list:
    520               list.tk.call('tixDoWhenIdle', str(rh), 'attachwidget', str(list)))
    521 
    522 def SList_reset(rh, list):
    523     list.place(x=50, y=150, width=120, height=80)
    524     list.update()
    525     rh.attach_widget(list)
    526 
    527 def MkSWindow(w):
    528     """The ScrolledWindow widget allows you to scroll any kind of Tk
    529     widget. It is more versatile than a scrolled canvas widget.
    530     """
    531     global demo
    532 
    533     text = 'The Tix ScrolledWindow widget allows you to scroll any kind of Tk widget. It is more versatile than a scrolled canvas widget.'
    534 
    535     file = os.path.join(demo.dir, 'bitmaps', 'tix.gif')
    536     if not os.path.isfile(file):
    537         text += ' (Image missing)'
    538 
    539     top = Tix.Frame(w, width=330, height=330)
    540     bot = Tix.Frame(w)
    541     msg = Tix.Message(top,
    542                       relief=Tix.FLAT, width=200, anchor=Tix.N,
    543                       text=text)
    544 
    545     win = Tix.ScrolledWindow(top, scrollbar='auto')
    546 
    547     image1 = win.window.image_create('photo', file=file)
    548     lbl = Tix.Label(win.window, image=image1)
    549     lbl.pack(expand=1, fill=Tix.BOTH)
    550 
    551     win.place(x=30, y=150, width=190, height=120)
    552 
    553     rh = Tix.ResizeHandle(top, bg='black',
    554                           relief=Tix.RAISED,
    555                           handlesize=8, gridded=1, minwidth=50, minheight=30)
    556     btn = Tix.Button(bot, text='Reset', command=lambda w=rh, x=win: SWindow_reset(w,x))
    557     top.propagate(0)
    558     msg.pack(fill=Tix.X)
    559     btn.pack(anchor=Tix.CENTER)
    560     top.pack(expand=1, fill=Tix.BOTH)
    561     bot.pack(fill=Tix.BOTH)
    562 
    563     win.bind('<Map>', func=lambda arg=0, rh=rh, win=win:
    564              win.tk.call('tixDoWhenIdle', str(rh), 'attachwidget', str(win)))
    565 
    566 def SWindow_reset(rh, win):
    567     win.place(x=30, y=150, width=190, height=120)
    568     win.update()
    569     rh.attach_widget(win)
    570 
    571 def MkSText(w):
    572     """The TixScrolledWindow widget allows you to scroll any kind of Tk
    573     widget. It is more versatile than a scrolled canvas widget."""
    574     top = Tix.Frame(w, width=330, height=330)
    575     bot = Tix.Frame(w)
    576     msg = Tix.Message(top,
    577                       relief=Tix.FLAT, width=200, anchor=Tix.N,
    578                       text='The Tix ScrolledWindow widget allows you to scroll any kind of Tk widget. It is more versatile than a scrolled canvas widget.')
    579 
    580     win = Tix.ScrolledText(top, scrollbar='auto')
    581     win.text['wrap'] = 'none'
    582     win.text.insert(Tix.END, '''When -scrollbar is set to "auto", the
    583 scrollbars are shown only when needed.
    584 Additional modifiers can be used to force a
    585 scrollbar to be shown or hidden. For example,
    586 "auto -y" means the horizontal scrollbar
    587 should be shown when needed but the vertical
    588 scrollbar should always be hidden;
    589 "auto +x" means the vertical scrollbar
    590 should be shown when needed but the horizontal
    591 scrollbar should always be shown, and so on.'''
    592 )
    593     win.place(x=30, y=150, width=190, height=100)
    594 
    595     rh = Tix.ResizeHandle(top, bg='black',
    596                           relief=Tix.RAISED,
    597                           handlesize=8, gridded=1, minwidth=50, minheight=30)
    598     btn = Tix.Button(bot, text='Reset', command=lambda w=rh, x=win: SText_reset(w,x))
    599     top.propagate(0)
    600     msg.pack(fill=Tix.X)
    601     btn.pack(anchor=Tix.CENTER)
    602     top.pack(expand=1, fill=Tix.BOTH)
    603     bot.pack(fill=Tix.BOTH)
    604     win.bind('<Map>', func=lambda arg=0, rh=rh, win=win:
    605              win.tk.call('tixDoWhenIdle', str(rh), 'attachwidget', str(win)))
    606 
    607 def SText_reset(rh, win):
    608     win.place(x=30, y=150, width=190, height=120)
    609     win.update()
    610     rh.attach_widget(win)
    611 
    612 def MkManager(nb, name):
    613     w = nb.page(name)
    614     options='label.padX 4'
    615 
    616     pane = Tix.LabelFrame(w, label='Tix.PanedWindow', options=options)
    617     note = Tix.LabelFrame(w, label='Tix.NoteBook', options=options)
    618 
    619     MkPanedWindow(pane.frame)
    620     MkNoteBook(note.frame)
    621 
    622     pane.form(top=0, left=0, right=note, bottom=-1)
    623     note.form(top=0, right=-1, bottom=-1)
    624 
    625 def MkPanedWindow(w):
    626     """The PanedWindow widget allows the user to interactively manipulate
    627     the sizes of several panes. The panes can be arranged either vertically
    628     or horizontally.
    629     """
    630     msg = Tix.Message(w,
    631                       relief=Tix.FLAT, width=240, anchor=Tix.N,
    632                       text='The PanedWindow widget allows the user to interactively manipulate the sizes of several panes. The panes can be arranged either vertically or horizontally.')
    633     group = Tix.LabelEntry(w, label='Newsgroup:', options='entry.width 25')
    634     group.entry.insert(0,'comp.lang.python')
    635     pane = Tix.PanedWindow(w, orientation='vertical')
    636 
    637     p1 = pane.add('list', min=70, size=100)
    638     p2 = pane.add('text', min=70)
    639     list = Tix.ScrolledListBox(p1)
    640     text = Tix.ScrolledText(p2)
    641 
    642     list.listbox.insert(Tix.END, "  12324 Re: Tkinter is good for your health")
    643     list.listbox.insert(Tix.END, "+ 12325 Re: Tkinter is good for your health")
    644     list.listbox.insert(Tix.END, "+ 12326 Re: Tix is even better for your health (Was: Tkinter is good...)")
    645     list.listbox.insert(Tix.END, "  12327 Re: Tix is even better for your health (Was: Tkinter is good...)")
    646     list.listbox.insert(Tix.END, "+ 12328 Re: Tix is even better for your health (Was: Tkinter is good...)")
    647     list.listbox.insert(Tix.END, "  12329 Re: Tix is even better for your health (Was: Tkinter is good...)")
    648     list.listbox.insert(Tix.END, "+ 12330 Re: Tix is even better for your health (Was: Tkinter is good...)")
    649 
    650     text.text['bg'] = list.listbox['bg']
    651     text.text['wrap'] = 'none'
    652     text.text.insert(Tix.END, """
    653 Mon, 19 Jun 1995 11:39:52        comp.lang.python              Thread   34 of  220
    654 Lines 353       A new way to put text and bitmaps together iNo responses
    655 ioi (at] blue.seas.upenn.edu                Ioi K. Lam at University of Pennsylvania
    656 
    657 Hi,
    658 
    659 I have implemented a new image type called "compound". It allows you
    660 to glue together a bunch of bitmaps, images and text strings together
    661 to form a bigger image. Then you can use this image with widgets that
    662 support the -image option. For example, you can display a text string
    663 together with a bitmap, at the same time, inside a TK button widget.
    664 """)
    665     list.pack(expand=1, fill=Tix.BOTH, padx=4, pady=6)
    666     text.pack(expand=1, fill=Tix.BOTH, padx=4, pady=6)
    667 
    668     msg.pack(side=Tix.TOP, padx=3, pady=3, fill=Tix.BOTH)
    669     group.pack(side=Tix.TOP, padx=3, pady=3, fill=Tix.BOTH)
    670     pane.pack(side=Tix.TOP, padx=3, pady=3, fill=Tix.BOTH, expand=1)
    671 
    672 def MkNoteBook(w):
    673     msg = Tix.Message(w,
    674                       relief=Tix.FLAT, width=240, anchor=Tix.N,
    675                       text='The NoteBook widget allows you to layout a complex interface into individual pages.')
    676     # prefix = Tix.OptionName(w)
    677     # if not prefix: prefix = ''
    678     # w.option_add('*' + prefix + '*TixNoteBook*tagPadX', 8)
    679     options = "entry.width %d label.width %d label.anchor %s" % (10, 18, Tix.E)
    680 
    681     nb = Tix.NoteBook(w, ipadx=6, ipady=6, options=options)
    682     nb.add('hard_disk', label="Hard Disk", underline=0)
    683     nb.add('network', label="Network", underline=0)
    684 
    685     # Frame for the buttons that are present on all pages
    686     common = Tix.Frame(nb.hard_disk)
    687     common.pack(side=Tix.RIGHT, padx=2, pady=2, fill=Tix.Y)
    688     CreateCommonButtons(common)
    689 
    690     # Widgets belonging only to this page
    691     a = Tix.Control(nb.hard_disk, value=12, label='Access Time: ')
    692     w = Tix.Control(nb.hard_disk, value=400, label='Write Throughput: ')
    693     r = Tix.Control(nb.hard_disk, value=400, label='Read Throughput: ')
    694     c = Tix.Control(nb.hard_disk, value=1021, label='Capacity: ')
    695     a.pack(side=Tix.TOP, padx=20, pady=2)
    696     w.pack(side=Tix.TOP, padx=20, pady=2)
    697     r.pack(side=Tix.TOP, padx=20, pady=2)
    698     c.pack(side=Tix.TOP, padx=20, pady=2)
    699 
    700     common = Tix.Frame(nb.network)
    701     common.pack(side=Tix.RIGHT, padx=2, pady=2, fill=Tix.Y)
    702     CreateCommonButtons(common)
    703 
    704     a = Tix.Control(nb.network, value=12, label='Access Time: ')
    705     w = Tix.Control(nb.network, value=400, label='Write Throughput: ')
    706     r = Tix.Control(nb.network, value=400, label='Read Throughput: ')
    707     c = Tix.Control(nb.network, value=1021, label='Capacity: ')
    708     u = Tix.Control(nb.network, value=10, label='Users: ')
    709     a.pack(side=Tix.TOP, padx=20, pady=2)
    710     w.pack(side=Tix.TOP, padx=20, pady=2)
    711     r.pack(side=Tix.TOP, padx=20, pady=2)
    712     c.pack(side=Tix.TOP, padx=20, pady=2)
    713     u.pack(side=Tix.TOP, padx=20, pady=2)
    714 
    715     msg.pack(side=Tix.TOP, padx=3, pady=3, fill=Tix.BOTH)
    716     nb.pack(side=Tix.TOP, padx=5, pady=5, fill=Tix.BOTH, expand=1)
    717 
    718 def CreateCommonButtons(f):
    719     ok = Tix.Button(f, text='OK', width = 6)
    720     cancel = Tix.Button(f, text='Cancel', width = 6)
    721     ok.pack(side=Tix.TOP, padx=2, pady=2)
    722     cancel.pack(side=Tix.TOP, padx=2, pady=2)
    723 
    724 def MkDirList(nb, name):
    725     w = nb.page(name)
    726     options = "label.padX 4"
    727 
    728     dir = Tix.LabelFrame(w, label='Tix.DirList', options=options)
    729     fsbox = Tix.LabelFrame(w, label='Tix.ExFileSelectBox', options=options)
    730     MkDirListWidget(dir.frame)
    731     MkExFileWidget(fsbox.frame)
    732     dir.form(top=0, left=0, right='%40', bottom=-1)
    733     fsbox.form(top=0, left='%40', right=-1, bottom=-1)
    734 
    735 def MkDirListWidget(w):
    736     """The TixDirList widget gives a graphical representation of the file
    737     system directory and makes it easy for the user to choose and access
    738     directories.
    739     """
    740     msg = Tix.Message(w,
    741                       relief=Tix.FLAT, width=240, anchor=Tix.N,
    742                       text='The Tix DirList widget gives a graphical representation of the file system directory and makes it easy for the user to choose and access directories.')
    743     dirlist = Tix.DirList(w, options='hlist.padY 1 hlist.width 25 hlist.height 16')
    744     msg.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH, padx=3, pady=3)
    745     dirlist.pack(side=Tix.TOP, padx=3, pady=3)
    746 
    747 def MkExFileWidget(w):
    748     """The TixExFileSelectBox widget is more user friendly than the Motif
    749     style FileSelectBox.  """
    750     msg = Tix.Message(w,
    751                       relief=Tix.FLAT, width=240, anchor=Tix.N,
    752                       text='The Tix ExFileSelectBox widget is more user friendly than the Motif style FileSelectBox.')
    753     # There's a bug in the ComboBoxes - the scrolledlistbox is destroyed
    754     box = Tix.ExFileSelectBox(w, bd=2, relief=Tix.RAISED)
    755     msg.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH, padx=3, pady=3)
    756     box.pack(side=Tix.TOP, padx=3, pady=3)
    757 
    758 ###
    759 ### List of all the demos we want to show off
    760 comments = {'widget' : 'Widget Demos', 'image' : 'Image Demos'}
    761 samples = {'Balloon'            : 'Balloon',
    762            'Button Box'         : 'BtnBox',
    763            'Combo Box'          : 'ComboBox',
    764            'Compound Image'     : 'CmpImg',
    765            'Directory List'     : 'DirList',
    766            'Directory Tree'     : 'DirTree',
    767            'Control'            : 'Control',
    768            'Notebook'           : 'NoteBook',
    769            'Option Menu'        : 'OptMenu',
    770            'Paned Window'       : 'PanedWin',
    771            'Popup Menu'         : 'PopMenu',
    772            'ScrolledHList (1)'  : 'SHList1',
    773            'ScrolledHList (2)'  : 'SHList2',
    774            'Tree (dynamic)'     : 'Tree'
    775 }
    776 
    777 # There are still a lot of demos to be translated:
    778 ##      set root {
    779 ##          {d "File Selectors"         file    }
    780 ##          {d "Hierachical ListBox"    hlist   }
    781 ##          {d "Tabular ListBox"        tlist   {c tixTList}}
    782 ##          {d "Grid Widget"            grid    {c tixGrid}}
    783 ##          {d "Manager Widgets"        manager }
    784 ##          {d "Scrolled Widgets"       scroll  }
    785 ##          {d "Miscellaneous Widgets"  misc    }
    786 ##          {d "Image Types"            image   }
    787 ##      }
    788 ##
    789 ##      set image {
    790 ##          {d "Compound Image"         cmpimg  }
    791 ##          {d "XPM Image"              xpm     {i pixmap}}
    792 ##      }
    793 ##
    794 ##      set cmpimg {
    795 ##done      {f "In Buttons"             CmpImg.tcl      }
    796 ##          {f "In NoteBook"            CmpImg2.tcl     }
    797 ##          {f "Notebook Color Tabs"    CmpImg4.tcl     }
    798 ##          {f "Icons"                  CmpImg3.tcl     }
    799 ##      }
    800 ##
    801 ##      set xpm {
    802 ##          {f "In Button"              Xpm.tcl         {i pixmap}}
    803 ##          {f "In Menu"                Xpm1.tcl        {i pixmap}}
    804 ##      }
    805 ##
    806 ##      set file {
    807 ##added     {f DirList                          DirList.tcl     }
    808 ##added     {f DirTree                          DirTree.tcl     }
    809 ##          {f DirSelectDialog                  DirDlg.tcl      }
    810 ##          {f ExFileSelectDialog               EFileDlg.tcl    }
    811 ##          {f FileSelectDialog                 FileDlg.tcl     }
    812 ##          {f FileEntry                        FileEnt.tcl     }
    813 ##      }
    814 ##
    815 ##      set hlist {
    816 ##          {f HList                    HList1.tcl      }
    817 ##          {f CheckList                ChkList.tcl     {c tixCheckList}}
    818 ##done      {f "ScrolledHList (1)"      SHList.tcl      }
    819 ##done      {f "ScrolledHList (2)"      SHList2.tcl     }
    820 ##done      {f Tree                     Tree.tcl        }
    821 ##done      {f "Tree (Dynamic)"         DynTree.tcl     {v win}}
    822 ##      }
    823 ##
    824 ##      set tlist {
    825 ##          {f "ScrolledTList (1)"      STList1.tcl     {c tixTList}}
    826 ##          {f "ScrolledTList (2)"      STList2.tcl     {c tixTList}}
    827 ##      }
    828 ##      global tcl_platform
    829 ##      #  This demo hangs windows
    830 ##      if {$tcl_platform(platform) != "windows"} {
    831 ##na    lappend tlist     {f "TList File Viewer"        STList3.tcl     {c tixTList}}
    832 ##      }
    833 ##
    834 ##      set grid {
    835 ##na        {f "Simple Grid"            SGrid0.tcl      {c tixGrid}}
    836 ##na        {f "ScrolledGrid"           SGrid1.tcl      {c tixGrid}}
    837 ##na        {f "Editable Grid"          EditGrid.tcl    {c tixGrid}}
    838 ##      }
    839 ##
    840 ##      set scroll {
    841 ##          {f ScrolledListBox          SListBox.tcl    }
    842 ##          {f ScrolledText             SText.tcl       }
    843 ##          {f ScrolledWindow           SWindow.tcl     }
    844 ##na        {f "Canvas Object View"     CObjView.tcl    {c tixCObjView}}
    845 ##      }
    846 ##
    847 ##      set manager {
    848 ##          {f ListNoteBook             ListNBK.tcl     }
    849 ##done      {f NoteBook                 NoteBook.tcl    }
    850 ##done      {f PanedWindow              PanedWin.tcl    }
    851 ##      }
    852 ##
    853 ##      set misc {
    854 ##done      {f Balloon                  Balloon.tcl     }
    855 ##done      {f ButtonBox                BtnBox.tcl      }
    856 ##done      {f ComboBox                 ComboBox.tcl    }
    857 ##done      {f Control                  Control.tcl     }
    858 ##          {f LabelEntry               LabEntry.tcl    }
    859 ##          {f LabelFrame               LabFrame.tcl    }
    860 ##          {f Meter                    Meter.tcl       {c tixMeter}}
    861 ##done      {f OptionMenu               OptMenu.tcl     }
    862 ##done      {f PopupMenu                PopMenu.tcl     }
    863 ##          {f Select                   Select.tcl      }
    864 ##          {f StdButtonBox             StdBBox.tcl     }
    865 ##      }
    866 ##
    867 
    868 stypes = {}
    869 stypes['widget'] = ['Balloon', 'Button Box', 'Combo Box', 'Control',
    870                     'Directory List', 'Directory Tree',
    871                     'Notebook', 'Option Menu', 'Popup Menu', 'Paned Window',
    872                     'ScrolledHList (1)', 'ScrolledHList (2)', 'Tree (dynamic)']
    873 stypes['image'] = ['Compound Image']
    874 
    875 def MkSample(nb, name):
    876     w = nb.page(name)
    877     options = "label.padX 4"
    878 
    879     pane = Tix.PanedWindow(w, orientation='horizontal')
    880     pane.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH)
    881     f1 = pane.add('list', expand='1')
    882     f2 = pane.add('text', expand='5')
    883     f1['relief'] = 'flat'
    884     f2['relief'] = 'flat'
    885 
    886     lab = Tix.LabelFrame(f1, label='Select a sample program:')
    887     lab.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH, padx=5, pady=5)
    888     lab1 = Tix.LabelFrame(f2, label='Source:')
    889     lab1.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH, padx=5, pady=5)
    890 
    891     slb = Tix.Tree(lab.frame, options='hlist.width 20')
    892     slb.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH, padx=5)
    893 
    894     stext = Tix.ScrolledText(lab1.frame, name='stext')
    895     font = root.tk.eval('tix option get fixed_font')
    896     stext.text.config(font=font)
    897 
    898     frame = Tix.Frame(lab1.frame, name='frame')
    899 
    900     run = Tix.Button(frame, text='Run ...', name='run')
    901     view = Tix.Button(frame, text='View Source ...', name='view')
    902     run.pack(side=Tix.LEFT, expand=0, fill=Tix.NONE)
    903     view.pack(side=Tix.LEFT, expand=0, fill=Tix.NONE)
    904 
    905     stext.text['bg'] = slb.hlist['bg']
    906     stext.text['state'] = 'disabled'
    907     stext.text['wrap'] = 'none'
    908     stext.text['width'] = 80
    909 
    910     frame.pack(side=Tix.BOTTOM, expand=0, fill=Tix.X, padx=7)
    911     stext.pack(side=Tix.TOP, expand=0, fill=Tix.BOTH, padx=7)
    912 
    913     slb.hlist['separator'] = '.'
    914     slb.hlist['width'] = 25
    915     slb.hlist['drawbranch'] = 0
    916     slb.hlist['indent'] = 10
    917     slb.hlist['wideselect'] = 1
    918     slb.hlist['command'] = lambda args=0, w=w,slb=slb,stext=stext,run=run,view=view: Sample_Action(w, slb, stext, run, view, 'run')
    919     slb.hlist['browsecmd'] = lambda args=0, w=w,slb=slb,stext=stext,run=run,view=view: Sample_Action(w, slb, stext, run, view, 'browse')
    920 
    921     run['command']      = lambda args=0, w=w,slb=slb,stext=stext,run=run,view=view: Sample_Action(w, slb, stext, run, view, 'run')
    922     view['command'] = lambda args=0, w=w,slb=slb,stext=stext,run=run,view=view: Sample_Action(w, slb, stext, run, view, 'view')
    923 
    924     for type in ['widget', 'image']:
    925         if type != 'widget':
    926             x = Tix.Frame(slb.hlist, bd=2, height=2, width=150,
    927                           relief=Tix.SUNKEN, bg=slb.hlist['bg'])
    928             slb.hlist.add_child(itemtype=Tix.WINDOW, window=x, state='disabled')
    929         x = slb.hlist.add_child(itemtype=Tix.TEXT, state='disabled',
    930                                 text=comments[type])
    931         for key in stypes[type]:
    932             slb.hlist.add_child(x, itemtype=Tix.TEXT, data=key,
    933                                 text=key)
    934     slb.hlist.selection_clear()
    935 
    936     run['state'] = 'disabled'
    937     view['state'] = 'disabled'
    938 
    939 def Sample_Action(w, slb, stext, run, view, action):
    940     global demo
    941 
    942     hlist = slb.hlist
    943     anchor = hlist.info_anchor()
    944     if not anchor:
    945         run['state'] = 'disabled'
    946         view['state'] = 'disabled'
    947     elif not hlist.info_parent(anchor):
    948         # a comment
    949         return
    950 
    951     run['state'] = 'normal'
    952     view['state'] = 'normal'
    953     key = hlist.info_data(anchor)
    954     title = key
    955     prog = samples[key]
    956 
    957     if action == 'run':
    958         exec('import ' + prog)
    959         w = Tix.Toplevel()
    960         w.title(title)
    961         rtn = eval(prog + '.RunSample')
    962         rtn(w)
    963     elif action == 'view':
    964         w = Tix.Toplevel()
    965         w.title('Source view: ' + title)
    966         LoadFile(w, demo.dir + '/samples/' + prog + '.py')
    967     elif action == 'browse':
    968         ReadFile(stext.text, demo.dir + '/samples/' + prog + '.py')
    969 
    970 def LoadFile(w, fname):
    971     global root
    972     b = Tix.Button(w, text='Close', command=w.destroy)
    973     t = Tix.ScrolledText(w)
    974     #    b.form(left=0, bottom=0, padx=4, pady=4)
    975     #    t.form(left=0, bottom=b, right='-0', top=0)
    976     t.pack()
    977     b.pack()
    978 
    979     font = root.tk.eval('tix option get fixed_font')
    980     t.text.config(font=font)
    981     t.text['bd'] = 2
    982     t.text['wrap'] = 'none'
    983 
    984     ReadFile(t.text, fname)
    985 
    986 def ReadFile(w, fname):
    987     old_state = w['state']
    988     w['state'] = 'normal'
    989     w.delete('0.0', Tix.END)
    990 
    991     try:
    992         f = open(fname)
    993         lines = f.readlines()
    994         for s in lines:
    995             w.insert(Tix.END, s)
    996         f.close()
    997     finally:
    998 #       w.see('1.0')
    999         w['state'] = old_state
   1000 
   1001 if __name__ == '__main__':
   1002     root = Tix.Tk()
   1003     RunMain(root)
   1004