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