1"""Wrapper functions for Tcl/Tk. 2 3Tkinter provides classes which allow the display, positioning and 4control of widgets. Toplevel widgets are Tk and Toplevel. Other 5widgets are Frame, Label, Entry, Text, Canvas, Button, Radiobutton, 6Checkbutton, Scale, Listbox, Scrollbar, OptionMenu, Spinbox 7LabelFrame and PanedWindow. 8 9Properties of the widgets are specified with keyword arguments. 10Keyword arguments have the same name as the corresponding resource 11under Tk. 12 13Widgets are positioned with one of the geometry managers Place, Pack 14or Grid. These managers can be called with methods place, pack, grid 15available in every Widget. 16 17Actions are bound to events by resources (e.g. keyword argument 18command) or with the method bind. 19 20Example (Hello, World): 21import Tkinter 22from Tkconstants import * 23tk = Tkinter.Tk() 24frame = Tkinter.Frame(tk, relief=RIDGE, borderwidth=2) 25frame.pack(fill=BOTH,expand=1) 26label = Tkinter.Label(frame, text="Hello, World") 27label.pack(fill=X, expand=1) 28button = Tkinter.Button(frame,text="Exit",command=tk.destroy) 29button.pack(side=BOTTOM) 30tk.mainloop() 31""" 32 33__version__ = "$Revision: 81008 $" 34 35import sys 36if sys.platform == "win32": 37 # Attempt to configure Tcl/Tk without requiring PATH 38 import FixTk 39import _tkinter # If this fails your Python may not be configured for Tk 40tkinter = _tkinter # b/w compat for export 41TclError = _tkinter.TclError 42from types import * 43from Tkconstants import * 44import re 45 46wantobjects = 1 47 48TkVersion = float(_tkinter.TK_VERSION) 49TclVersion = float(_tkinter.TCL_VERSION) 50 51READABLE = _tkinter.READABLE 52WRITABLE = _tkinter.WRITABLE 53EXCEPTION = _tkinter.EXCEPTION 54 55# These are not always defined, e.g. not on Win32 with Tk 8.0 :-( 56try: _tkinter.createfilehandler 57except AttributeError: _tkinter.createfilehandler = None 58try: _tkinter.deletefilehandler 59except AttributeError: _tkinter.deletefilehandler = None 60 61 62_magic_re = re.compile(r'([\\{}])') 63_space_re = re.compile(r'([\s])') 64 65def _join(value): 66 """Internal function.""" 67 return ' '.join(map(_stringify, value)) 68 69def _stringify(value): 70 """Internal function.""" 71 if isinstance(value, (list, tuple)): 72 if len(value) == 1: 73 value = _stringify(value[0]) 74 if _magic_re.search(value): 75 value = '{%s}' % value 76 else: 77 value = '{%s}' % _join(value) 78 else: 79 if isinstance(value, str): 80 value = unicode(value, 'utf-8') 81 elif not isinstance(value, unicode): 82 value = str(value) 83 if not value: 84 value = '{}' 85 elif _magic_re.search(value): 86 # add '\' before special characters and spaces 87 value = _magic_re.sub(r'\\\1', value) 88 value = value.replace('\n', r'\n') 89 value = _space_re.sub(r'\\\1', value) 90 if value[0] == '"': 91 value = '\\' + value 92 elif value[0] == '"' or _space_re.search(value): 93 value = '{%s}' % value 94 return value 95 96def _flatten(tuple): 97 """Internal function.""" 98 res = () 99 for item in tuple: 100 if type(item) in (TupleType, ListType): 101 res = res + _flatten(item) 102 elif item is not None: 103 res = res + (item,) 104 return res 105 106try: _flatten = _tkinter._flatten 107except AttributeError: pass 108 109def _cnfmerge(cnfs): 110 """Internal function.""" 111 if type(cnfs) is DictionaryType: 112 return cnfs 113 elif type(cnfs) in (NoneType, StringType): 114 return cnfs 115 else: 116 cnf = {} 117 for c in _flatten(cnfs): 118 try: 119 cnf.update(c) 120 except (AttributeError, TypeError), msg: 121 print "_cnfmerge: fallback due to:", msg 122 for k, v in c.items(): 123 cnf[k] = v 124 return cnf 125 126try: _cnfmerge = _tkinter._cnfmerge 127except AttributeError: pass 128 129def _splitdict(tk, v, cut_minus=True, conv=None): 130 """Return a properly formatted dict built from Tcl list pairs. 131 132 If cut_minus is True, the supposed '-' prefix will be removed from 133 keys. If conv is specified, it is used to convert values. 134 135 Tcl list is expected to contain an even number of elements. 136 """ 137 t = tk.splitlist(v) 138 if len(t) % 2: 139 raise RuntimeError('Tcl list representing a dict is expected ' 140 'to contain an even number of elements') 141 it = iter(t) 142 dict = {} 143 for key, value in zip(it, it): 144 key = str(key) 145 if cut_minus and key[0] == '-': 146 key = key[1:] 147 if conv: 148 value = conv(value) 149 dict[key] = value 150 return dict 151 152class Event: 153 """Container for the properties of an event. 154 155 Instances of this type are generated if one of the following events occurs: 156 157 KeyPress, KeyRelease - for keyboard events 158 ButtonPress, ButtonRelease, Motion, Enter, Leave, MouseWheel - for mouse events 159 Visibility, Unmap, Map, Expose, FocusIn, FocusOut, Circulate, 160 Colormap, Gravity, Reparent, Property, Destroy, Activate, 161 Deactivate - for window events. 162 163 If a callback function for one of these events is registered 164 using bind, bind_all, bind_class, or tag_bind, the callback is 165 called with an Event as first argument. It will have the 166 following attributes (in braces are the event types for which 167 the attribute is valid): 168 169 serial - serial number of event 170 num - mouse button pressed (ButtonPress, ButtonRelease) 171 focus - whether the window has the focus (Enter, Leave) 172 height - height of the exposed window (Configure, Expose) 173 width - width of the exposed window (Configure, Expose) 174 keycode - keycode of the pressed key (KeyPress, KeyRelease) 175 state - state of the event as a number (ButtonPress, ButtonRelease, 176 Enter, KeyPress, KeyRelease, 177 Leave, Motion) 178 state - state as a string (Visibility) 179 time - when the event occurred 180 x - x-position of the mouse 181 y - y-position of the mouse 182 x_root - x-position of the mouse on the screen 183 (ButtonPress, ButtonRelease, KeyPress, KeyRelease, Motion) 184 y_root - y-position of the mouse on the screen 185 (ButtonPress, ButtonRelease, KeyPress, KeyRelease, Motion) 186 char - pressed character (KeyPress, KeyRelease) 187 send_event - see X/Windows documentation 188 keysym - keysym of the event as a string (KeyPress, KeyRelease) 189 keysym_num - keysym of the event as a number (KeyPress, KeyRelease) 190 type - type of the event as a number 191 widget - widget in which the event occurred 192 delta - delta of wheel movement (MouseWheel) 193 """ 194 pass 195 196_support_default_root = 1 197_default_root = None 198 199def NoDefaultRoot(): 200 """Inhibit setting of default root window. 201 202 Call this function to inhibit that the first instance of 203 Tk is used for windows without an explicit parent window. 204 """ 205 global _support_default_root 206 _support_default_root = 0 207 global _default_root 208 _default_root = None 209 del _default_root 210 211def _tkerror(err): 212 """Internal function.""" 213 pass 214 215def _exit(code=0): 216 """Internal function. Calling it will raise the exception SystemExit.""" 217 try: 218 code = int(code) 219 except ValueError: 220 pass 221 raise SystemExit, code 222 223_varnum = 0 224class Variable: 225 """Class to define value holders for e.g. buttons. 226 227 Subclasses StringVar, IntVar, DoubleVar, BooleanVar are specializations 228 that constrain the type of the value returned from get().""" 229 _default = "" 230 _tclCommands = None 231 def __init__(self, master=None, value=None, name=None): 232 """Construct a variable 233 234 MASTER can be given as master widget. 235 VALUE is an optional value (defaults to "") 236 NAME is an optional Tcl name (defaults to PY_VARnum). 237 238 If NAME matches an existing variable and VALUE is omitted 239 then the existing value is retained. 240 """ 241 global _varnum 242 if not master: 243 master = _default_root 244 self._root = master._root() 245 self._tk = master.tk 246 if name: 247 self._name = name 248 else: 249 self._name = 'PY_VAR' + repr(_varnum) 250 _varnum += 1 251 if value is not None: 252 self.set(value) 253 elif not self._tk.getboolean(self._tk.call("info", "exists", self._name)): 254 self.set(self._default) 255 def __del__(self): 256 """Unset the variable in Tcl.""" 257 if self._tk is None: 258 return 259 if self._tk.getboolean(self._tk.call("info", "exists", self._name)): 260 self._tk.globalunsetvar(self._name) 261 if self._tclCommands is not None: 262 for name in self._tclCommands: 263 #print '- Tkinter: deleted command', name 264 self._tk.deletecommand(name) 265 self._tclCommands = None 266 def __str__(self): 267 """Return the name of the variable in Tcl.""" 268 return self._name 269 def set(self, value): 270 """Set the variable to VALUE.""" 271 return self._tk.globalsetvar(self._name, value) 272 def get(self): 273 """Return value of variable.""" 274 return self._tk.globalgetvar(self._name) 275 def trace_variable(self, mode, callback): 276 """Define a trace callback for the variable. 277 278 MODE is one of "r", "w", "u" for read, write, undefine. 279 CALLBACK must be a function which is called when 280 the variable is read, written or undefined. 281 282 Return the name of the callback. 283 """ 284 f = CallWrapper(callback, None, self._root).__call__ 285 cbname = repr(id(f)) 286 try: 287 callback = callback.im_func 288 except AttributeError: 289 pass 290 try: 291 cbname = cbname + callback.__name__ 292 except AttributeError: 293 pass 294 self._tk.createcommand(cbname, f) 295 if self._tclCommands is None: 296 self._tclCommands = [] 297 self._tclCommands.append(cbname) 298 self._tk.call("trace", "variable", self._name, mode, cbname) 299 return cbname 300 trace = trace_variable 301 def trace_vdelete(self, mode, cbname): 302 """Delete the trace callback for a variable. 303 304 MODE is one of "r", "w", "u" for read, write, undefine. 305 CBNAME is the name of the callback returned from trace_variable or trace. 306 """ 307 self._tk.call("trace", "vdelete", self._name, mode, cbname) 308 cbname = self._tk.splitlist(cbname)[0] 309 for m, ca in self.trace_vinfo(): 310 if self._tk.splitlist(ca)[0] == cbname: 311 break 312 else: 313 self._tk.deletecommand(cbname) 314 try: 315 self._tclCommands.remove(cbname) 316 except ValueError: 317 pass 318 def trace_vinfo(self): 319 """Return all trace callback information.""" 320 return map(self._tk.splitlist, self._tk.splitlist( 321 self._tk.call("trace", "vinfo", self._name))) 322 def __eq__(self, other): 323 """Comparison for equality (==). 324 325 Note: if the Variable's master matters to behavior 326 also compare self._master == other._master 327 """ 328 return self.__class__.__name__ == other.__class__.__name__ \ 329 and self._name == other._name 330 331class StringVar(Variable): 332 """Value holder for strings variables.""" 333 _default = "" 334 def __init__(self, master=None, value=None, name=None): 335 """Construct a string variable. 336 337 MASTER can be given as master widget. 338 VALUE is an optional value (defaults to "") 339 NAME is an optional Tcl name (defaults to PY_VARnum). 340 341 If NAME matches an existing variable and VALUE is omitted 342 then the existing value is retained. 343 """ 344 Variable.__init__(self, master, value, name) 345 346 def get(self): 347 """Return value of variable as string.""" 348 value = self._tk.globalgetvar(self._name) 349 if isinstance(value, basestring): 350 return value 351 return str(value) 352 353class IntVar(Variable): 354 """Value holder for integer variables.""" 355 _default = 0 356 def __init__(self, master=None, value=None, name=None): 357 """Construct an integer variable. 358 359 MASTER can be given as master widget. 360 VALUE is an optional value (defaults to 0) 361 NAME is an optional Tcl name (defaults to PY_VARnum). 362 363 If NAME matches an existing variable and VALUE is omitted 364 then the existing value is retained. 365 """ 366 Variable.__init__(self, master, value, name) 367 368 def set(self, value): 369 """Set the variable to value, converting booleans to integers.""" 370 if isinstance(value, bool): 371 value = int(value) 372 return Variable.set(self, value) 373 374 def get(self): 375 """Return the value of the variable as an integer.""" 376 return getint(self._tk.globalgetvar(self._name)) 377 378class DoubleVar(Variable): 379 """Value holder for float variables.""" 380 _default = 0.0 381 def __init__(self, master=None, value=None, name=None): 382 """Construct a float variable. 383 384 MASTER can be given as master widget. 385 VALUE is an optional value (defaults to 0.0) 386 NAME is an optional Tcl name (defaults to PY_VARnum). 387 388 If NAME matches an existing variable and VALUE is omitted 389 then the existing value is retained. 390 """ 391 Variable.__init__(self, master, value, name) 392 393 def get(self): 394 """Return the value of the variable as a float.""" 395 return getdouble(self._tk.globalgetvar(self._name)) 396 397class BooleanVar(Variable): 398 """Value holder for boolean variables.""" 399 _default = False 400 def __init__(self, master=None, value=None, name=None): 401 """Construct a boolean variable. 402 403 MASTER can be given as master widget. 404 VALUE is an optional value (defaults to False) 405 NAME is an optional Tcl name (defaults to PY_VARnum). 406 407 If NAME matches an existing variable and VALUE is omitted 408 then the existing value is retained. 409 """ 410 Variable.__init__(self, master, value, name) 411 412 def set(self, value): 413 """Set the variable to VALUE.""" 414 return self._tk.globalsetvar(self._name, self._tk.getboolean(value)) 415 416 def get(self): 417 """Return the value of the variable as a bool.""" 418 return self._tk.getboolean(self._tk.globalgetvar(self._name)) 419 420def mainloop(n=0): 421 """Run the main loop of Tcl.""" 422 _default_root.tk.mainloop(n) 423 424getint = int 425 426getdouble = float 427 428def getboolean(s): 429 """Convert true and false to integer values 1 and 0.""" 430 return _default_root.tk.getboolean(s) 431 432# Methods defined on both toplevel and interior widgets 433class Misc: 434 """Internal class. 435 436 Base class which defines methods common for interior widgets.""" 437 438 # XXX font command? 439 _tclCommands = None 440 def destroy(self): 441 """Internal function. 442 443 Delete all Tcl commands created for 444 this widget in the Tcl interpreter.""" 445 if self._tclCommands is not None: 446 for name in self._tclCommands: 447 #print '- Tkinter: deleted command', name 448 self.tk.deletecommand(name) 449 self._tclCommands = None 450 def deletecommand(self, name): 451 """Internal function. 452 453 Delete the Tcl command provided in NAME.""" 454 #print '- Tkinter: deleted command', name 455 self.tk.deletecommand(name) 456 try: 457 self._tclCommands.remove(name) 458 except ValueError: 459 pass 460 def tk_strictMotif(self, boolean=None): 461 """Set Tcl internal variable, whether the look and feel 462 should adhere to Motif. 463 464 A parameter of 1 means adhere to Motif (e.g. no color 465 change if mouse passes over slider). 466 Returns the set value.""" 467 return self.tk.getboolean(self.tk.call( 468 'set', 'tk_strictMotif', boolean)) 469 def tk_bisque(self): 470 """Change the color scheme to light brown as used in Tk 3.6 and before.""" 471 self.tk.call('tk_bisque') 472 def tk_setPalette(self, *args, **kw): 473 """Set a new color scheme for all widget elements. 474 475 A single color as argument will cause that all colors of Tk 476 widget elements are derived from this. 477 Alternatively several keyword parameters and its associated 478 colors can be given. The following keywords are valid: 479 activeBackground, foreground, selectColor, 480 activeForeground, highlightBackground, selectBackground, 481 background, highlightColor, selectForeground, 482 disabledForeground, insertBackground, troughColor.""" 483 self.tk.call(('tk_setPalette',) 484 + _flatten(args) + _flatten(kw.items())) 485 def tk_menuBar(self, *args): 486 """Do not use. Needed in Tk 3.6 and earlier.""" 487 # obsolete since Tk 4.0 488 import warnings 489 warnings.warn('tk_menuBar() does nothing and will be removed in 3.6', 490 DeprecationWarning, stacklevel=2) 491 def wait_variable(self, name='PY_VAR'): 492 """Wait until the variable is modified. 493 494 A parameter of type IntVar, StringVar, DoubleVar or 495 BooleanVar must be given.""" 496 self.tk.call('tkwait', 'variable', name) 497 waitvar = wait_variable # XXX b/w compat 498 def wait_window(self, window=None): 499 """Wait until a WIDGET is destroyed. 500 501 If no parameter is given self is used.""" 502 if window is None: 503 window = self 504 self.tk.call('tkwait', 'window', window._w) 505 def wait_visibility(self, window=None): 506 """Wait until the visibility of a WIDGET changes 507 (e.g. it appears). 508 509 If no parameter is given self is used.""" 510 if window is None: 511 window = self 512 self.tk.call('tkwait', 'visibility', window._w) 513 def setvar(self, name='PY_VAR', value='1'): 514 """Set Tcl variable NAME to VALUE.""" 515 self.tk.setvar(name, value) 516 def getvar(self, name='PY_VAR'): 517 """Return value of Tcl variable NAME.""" 518 return self.tk.getvar(name) 519 getint = int 520 getdouble = float 521 def getboolean(self, s): 522 """Return a boolean value for Tcl boolean values true and false given as parameter.""" 523 return self.tk.getboolean(s) 524 def focus_set(self): 525 """Direct input focus to this widget. 526 527 If the application currently does not have the focus 528 this widget will get the focus if the application gets 529 the focus through the window manager.""" 530 self.tk.call('focus', self._w) 531 focus = focus_set # XXX b/w compat? 532 def focus_force(self): 533 """Direct input focus to this widget even if the 534 application does not have the focus. Use with 535 caution!""" 536 self.tk.call('focus', '-force', self._w) 537 def focus_get(self): 538 """Return the widget which has currently the focus in the 539 application. 540 541 Use focus_displayof to allow working with several 542 displays. Return None if application does not have 543 the focus.""" 544 name = self.tk.call('focus') 545 if name == 'none' or not name: return None 546 return self._nametowidget(name) 547 def focus_displayof(self): 548 """Return the widget which has currently the focus on the 549 display where this widget is located. 550 551 Return None if the application does not have the focus.""" 552 name = self.tk.call('focus', '-displayof', self._w) 553 if name == 'none' or not name: return None 554 return self._nametowidget(name) 555 def focus_lastfor(self): 556 """Return the widget which would have the focus if top level 557 for this widget gets the focus from the window manager.""" 558 name = self.tk.call('focus', '-lastfor', self._w) 559 if name == 'none' or not name: return None 560 return self._nametowidget(name) 561 def tk_focusFollowsMouse(self): 562 """The widget under mouse will get automatically focus. Can not 563 be disabled easily.""" 564 self.tk.call('tk_focusFollowsMouse') 565 def tk_focusNext(self): 566 """Return the next widget in the focus order which follows 567 widget which has currently the focus. 568 569 The focus order first goes to the next child, then to 570 the children of the child recursively and then to the 571 next sibling which is higher in the stacking order. A 572 widget is omitted if it has the takefocus resource set 573 to 0.""" 574 name = self.tk.call('tk_focusNext', self._w) 575 if not name: return None 576 return self._nametowidget(name) 577 def tk_focusPrev(self): 578 """Return previous widget in the focus order. See tk_focusNext for details.""" 579 name = self.tk.call('tk_focusPrev', self._w) 580 if not name: return None 581 return self._nametowidget(name) 582 def after(self, ms, func=None, *args): 583 """Call function once after given time. 584 585 MS specifies the time in milliseconds. FUNC gives the 586 function which shall be called. Additional parameters 587 are given as parameters to the function call. Return 588 identifier to cancel scheduling with after_cancel.""" 589 if not func: 590 # I'd rather use time.sleep(ms*0.001) 591 self.tk.call('after', ms) 592 return None 593 else: 594 def callit(): 595 try: 596 func(*args) 597 finally: 598 try: 599 self.deletecommand(name) 600 except TclError: 601 pass 602 callit.__name__ = func.__name__ 603 name = self._register(callit) 604 return self.tk.call('after', ms, name) 605 def after_idle(self, func, *args): 606 """Call FUNC once if the Tcl main loop has no event to 607 process. 608 609 Return an identifier to cancel the scheduling with 610 after_cancel.""" 611 return self.after('idle', func, *args) 612 def after_cancel(self, id): 613 """Cancel scheduling of function identified with ID. 614 615 Identifier returned by after or after_idle must be 616 given as first parameter. 617 """ 618 if not id: 619 raise ValueError('id must be a valid identifier returned from ' 620 'after or after_idle') 621 try: 622 data = self.tk.call('after', 'info', id) 623 script = self.tk.splitlist(data)[0] 624 self.deletecommand(script) 625 except TclError: 626 pass 627 self.tk.call('after', 'cancel', id) 628 def bell(self, displayof=0): 629 """Ring a display's bell.""" 630 self.tk.call(('bell',) + self._displayof(displayof)) 631 632 # Clipboard handling: 633 def clipboard_get(self, **kw): 634 """Retrieve data from the clipboard on window's display. 635 636 The window keyword defaults to the root window of the Tkinter 637 application. 638 639 The type keyword specifies the form in which the data is 640 to be returned and should be an atom name such as STRING 641 or FILE_NAME. Type defaults to STRING, except on X11, where the default 642 is to try UTF8_STRING and fall back to STRING. 643 644 This command is equivalent to: 645 646 selection_get(CLIPBOARD) 647 """ 648 if 'type' not in kw and self._windowingsystem == 'x11': 649 try: 650 kw['type'] = 'UTF8_STRING' 651 return self.tk.call(('clipboard', 'get') + self._options(kw)) 652 except TclError: 653 del kw['type'] 654 return self.tk.call(('clipboard', 'get') + self._options(kw)) 655 656 def clipboard_clear(self, **kw): 657 """Clear the data in the Tk clipboard. 658 659 A widget specified for the optional displayof keyword 660 argument specifies the target display.""" 661 if 'displayof' not in kw: kw['displayof'] = self._w 662 self.tk.call(('clipboard', 'clear') + self._options(kw)) 663 def clipboard_append(self, string, **kw): 664 """Append STRING to the Tk clipboard. 665 666 A widget specified at the optional displayof keyword 667 argument specifies the target display. The clipboard 668 can be retrieved with selection_get.""" 669 if 'displayof' not in kw: kw['displayof'] = self._w 670 self.tk.call(('clipboard', 'append') + self._options(kw) 671 + ('--', string)) 672 # XXX grab current w/o window argument 673 def grab_current(self): 674 """Return widget which has currently the grab in this application 675 or None.""" 676 name = self.tk.call('grab', 'current', self._w) 677 if not name: return None 678 return self._nametowidget(name) 679 def grab_release(self): 680 """Release grab for this widget if currently set.""" 681 self.tk.call('grab', 'release', self._w) 682 def grab_set(self): 683 """Set grab for this widget. 684 685 A grab directs all events to this and descendant 686 widgets in the application.""" 687 self.tk.call('grab', 'set', self._w) 688 def grab_set_global(self): 689 """Set global grab for this widget. 690 691 A global grab directs all events to this and 692 descendant widgets on the display. Use with caution - 693 other applications do not get events anymore.""" 694 self.tk.call('grab', 'set', '-global', self._w) 695 def grab_status(self): 696 """Return None, "local" or "global" if this widget has 697 no, a local or a global grab.""" 698 status = self.tk.call('grab', 'status', self._w) 699 if status == 'none': status = None 700 return status 701 def option_add(self, pattern, value, priority = None): 702 """Set a VALUE (second parameter) for an option 703 PATTERN (first parameter). 704 705 An optional third parameter gives the numeric priority 706 (defaults to 80).""" 707 self.tk.call('option', 'add', pattern, value, priority) 708 def option_clear(self): 709 """Clear the option database. 710 711 It will be reloaded if option_add is called.""" 712 self.tk.call('option', 'clear') 713 def option_get(self, name, className): 714 """Return the value for an option NAME for this widget 715 with CLASSNAME. 716 717 Values with higher priority override lower values.""" 718 return self.tk.call('option', 'get', self._w, name, className) 719 def option_readfile(self, fileName, priority = None): 720 """Read file FILENAME into the option database. 721 722 An optional second parameter gives the numeric 723 priority.""" 724 self.tk.call('option', 'readfile', fileName, priority) 725 def selection_clear(self, **kw): 726 """Clear the current X selection.""" 727 if 'displayof' not in kw: kw['displayof'] = self._w 728 self.tk.call(('selection', 'clear') + self._options(kw)) 729 def selection_get(self, **kw): 730 """Return the contents of the current X selection. 731 732 A keyword parameter selection specifies the name of 733 the selection and defaults to PRIMARY. A keyword 734 parameter displayof specifies a widget on the display 735 to use. A keyword parameter type specifies the form of data to be 736 fetched, defaulting to STRING except on X11, where UTF8_STRING is tried 737 before STRING.""" 738 if 'displayof' not in kw: kw['displayof'] = self._w 739 if 'type' not in kw and self._windowingsystem == 'x11': 740 try: 741 kw['type'] = 'UTF8_STRING' 742 return self.tk.call(('selection', 'get') + self._options(kw)) 743 except TclError: 744 del kw['type'] 745 return self.tk.call(('selection', 'get') + self._options(kw)) 746 def selection_handle(self, command, **kw): 747 """Specify a function COMMAND to call if the X 748 selection owned by this widget is queried by another 749 application. 750 751 This function must return the contents of the 752 selection. The function will be called with the 753 arguments OFFSET and LENGTH which allows the chunking 754 of very long selections. The following keyword 755 parameters can be provided: 756 selection - name of the selection (default PRIMARY), 757 type - type of the selection (e.g. STRING, FILE_NAME).""" 758 name = self._register(command) 759 self.tk.call(('selection', 'handle') + self._options(kw) 760 + (self._w, name)) 761 def selection_own(self, **kw): 762 """Become owner of X selection. 763 764 A keyword parameter selection specifies the name of 765 the selection (default PRIMARY).""" 766 self.tk.call(('selection', 'own') + 767 self._options(kw) + (self._w,)) 768 def selection_own_get(self, **kw): 769 """Return owner of X selection. 770 771 The following keyword parameter can 772 be provided: 773 selection - name of the selection (default PRIMARY), 774 type - type of the selection (e.g. STRING, FILE_NAME).""" 775 if 'displayof' not in kw: kw['displayof'] = self._w 776 name = self.tk.call(('selection', 'own') + self._options(kw)) 777 if not name: return None 778 return self._nametowidget(name) 779 def send(self, interp, cmd, *args): 780 """Send Tcl command CMD to different interpreter INTERP to be executed.""" 781 return self.tk.call(('send', interp, cmd) + args) 782 def lower(self, belowThis=None): 783 """Lower this widget in the stacking order.""" 784 self.tk.call('lower', self._w, belowThis) 785 def tkraise(self, aboveThis=None): 786 """Raise this widget in the stacking order.""" 787 self.tk.call('raise', self._w, aboveThis) 788 lift = tkraise 789 def colormodel(self, value=None): 790 """Useless. Not implemented in Tk.""" 791 return self.tk.call('tk', 'colormodel', self._w, value) 792 def winfo_atom(self, name, displayof=0): 793 """Return integer which represents atom NAME.""" 794 args = ('winfo', 'atom') + self._displayof(displayof) + (name,) 795 return getint(self.tk.call(args)) 796 def winfo_atomname(self, id, displayof=0): 797 """Return name of atom with identifier ID.""" 798 args = ('winfo', 'atomname') \ 799 + self._displayof(displayof) + (id,) 800 return self.tk.call(args) 801 def winfo_cells(self): 802 """Return number of cells in the colormap for this widget.""" 803 return getint( 804 self.tk.call('winfo', 'cells', self._w)) 805 def winfo_children(self): 806 """Return a list of all widgets which are children of this widget.""" 807 result = [] 808 for child in self.tk.splitlist( 809 self.tk.call('winfo', 'children', self._w)): 810 try: 811 # Tcl sometimes returns extra windows, e.g. for 812 # menus; those need to be skipped 813 result.append(self._nametowidget(child)) 814 except KeyError: 815 pass 816 return result 817 818 def winfo_class(self): 819 """Return window class name of this widget.""" 820 return self.tk.call('winfo', 'class', self._w) 821 def winfo_colormapfull(self): 822 """Return true if at the last color request the colormap was full.""" 823 return self.tk.getboolean( 824 self.tk.call('winfo', 'colormapfull', self._w)) 825 def winfo_containing(self, rootX, rootY, displayof=0): 826 """Return the widget which is at the root coordinates ROOTX, ROOTY.""" 827 args = ('winfo', 'containing') \ 828 + self._displayof(displayof) + (rootX, rootY) 829 name = self.tk.call(args) 830 if not name: return None 831 return self._nametowidget(name) 832 def winfo_depth(self): 833 """Return the number of bits per pixel.""" 834 return getint(self.tk.call('winfo', 'depth', self._w)) 835 def winfo_exists(self): 836 """Return true if this widget exists.""" 837 return getint( 838 self.tk.call('winfo', 'exists', self._w)) 839 def winfo_fpixels(self, number): 840 """Return the number of pixels for the given distance NUMBER 841 (e.g. "3c") as float.""" 842 return getdouble(self.tk.call( 843 'winfo', 'fpixels', self._w, number)) 844 def winfo_geometry(self): 845 """Return geometry string for this widget in the form "widthxheight+X+Y".""" 846 return self.tk.call('winfo', 'geometry', self._w) 847 def winfo_height(self): 848 """Return height of this widget.""" 849 return getint( 850 self.tk.call('winfo', 'height', self._w)) 851 def winfo_id(self): 852 """Return identifier ID for this widget.""" 853 return int(self.tk.call('winfo', 'id', self._w), 0) 854 def winfo_interps(self, displayof=0): 855 """Return the name of all Tcl interpreters for this display.""" 856 args = ('winfo', 'interps') + self._displayof(displayof) 857 return self.tk.splitlist(self.tk.call(args)) 858 def winfo_ismapped(self): 859 """Return true if this widget is mapped.""" 860 return getint( 861 self.tk.call('winfo', 'ismapped', self._w)) 862 def winfo_manager(self): 863 """Return the window manager name for this widget.""" 864 return self.tk.call('winfo', 'manager', self._w) 865 def winfo_name(self): 866 """Return the name of this widget.""" 867 return self.tk.call('winfo', 'name', self._w) 868 def winfo_parent(self): 869 """Return the name of the parent of this widget.""" 870 return self.tk.call('winfo', 'parent', self._w) 871 def winfo_pathname(self, id, displayof=0): 872 """Return the pathname of the widget given by ID.""" 873 args = ('winfo', 'pathname') \ 874 + self._displayof(displayof) + (id,) 875 return self.tk.call(args) 876 def winfo_pixels(self, number): 877 """Rounded integer value of winfo_fpixels.""" 878 return getint( 879 self.tk.call('winfo', 'pixels', self._w, number)) 880 def winfo_pointerx(self): 881 """Return the x coordinate of the pointer on the root window.""" 882 return getint( 883 self.tk.call('winfo', 'pointerx', self._w)) 884 def winfo_pointerxy(self): 885 """Return a tuple of x and y coordinates of the pointer on the root window.""" 886 return self._getints( 887 self.tk.call('winfo', 'pointerxy', self._w)) 888 def winfo_pointery(self): 889 """Return the y coordinate of the pointer on the root window.""" 890 return getint( 891 self.tk.call('winfo', 'pointery', self._w)) 892 def winfo_reqheight(self): 893 """Return requested height of this widget.""" 894 return getint( 895 self.tk.call('winfo', 'reqheight', self._w)) 896 def winfo_reqwidth(self): 897 """Return requested width of this widget.""" 898 return getint( 899 self.tk.call('winfo', 'reqwidth', self._w)) 900 def winfo_rgb(self, color): 901 """Return tuple of decimal values for red, green, blue for 902 COLOR in this widget.""" 903 return self._getints( 904 self.tk.call('winfo', 'rgb', self._w, color)) 905 def winfo_rootx(self): 906 """Return x coordinate of upper left corner of this widget on the 907 root window.""" 908 return getint( 909 self.tk.call('winfo', 'rootx', self._w)) 910 def winfo_rooty(self): 911 """Return y coordinate of upper left corner of this widget on the 912 root window.""" 913 return getint( 914 self.tk.call('winfo', 'rooty', self._w)) 915 def winfo_screen(self): 916 """Return the screen name of this widget.""" 917 return self.tk.call('winfo', 'screen', self._w) 918 def winfo_screencells(self): 919 """Return the number of the cells in the colormap of the screen 920 of this widget.""" 921 return getint( 922 self.tk.call('winfo', 'screencells', self._w)) 923 def winfo_screendepth(self): 924 """Return the number of bits per pixel of the root window of the 925 screen of this widget.""" 926 return getint( 927 self.tk.call('winfo', 'screendepth', self._w)) 928 def winfo_screenheight(self): 929 """Return the number of pixels of the height of the screen of this widget 930 in pixel.""" 931 return getint( 932 self.tk.call('winfo', 'screenheight', self._w)) 933 def winfo_screenmmheight(self): 934 """Return the number of pixels of the height of the screen of 935 this widget in mm.""" 936 return getint( 937 self.tk.call('winfo', 'screenmmheight', self._w)) 938 def winfo_screenmmwidth(self): 939 """Return the number of pixels of the width of the screen of 940 this widget in mm.""" 941 return getint( 942 self.tk.call('winfo', 'screenmmwidth', self._w)) 943 def winfo_screenvisual(self): 944 """Return one of the strings directcolor, grayscale, pseudocolor, 945 staticcolor, staticgray, or truecolor for the default 946 colormodel of this screen.""" 947 return self.tk.call('winfo', 'screenvisual', self._w) 948 def winfo_screenwidth(self): 949 """Return the number of pixels of the width of the screen of 950 this widget in pixel.""" 951 return getint( 952 self.tk.call('winfo', 'screenwidth', self._w)) 953 def winfo_server(self): 954 """Return information of the X-Server of the screen of this widget in 955 the form "XmajorRminor vendor vendorVersion".""" 956 return self.tk.call('winfo', 'server', self._w) 957 def winfo_toplevel(self): 958 """Return the toplevel widget of this widget.""" 959 return self._nametowidget(self.tk.call( 960 'winfo', 'toplevel', self._w)) 961 def winfo_viewable(self): 962 """Return true if the widget and all its higher ancestors are mapped.""" 963 return getint( 964 self.tk.call('winfo', 'viewable', self._w)) 965 def winfo_visual(self): 966 """Return one of the strings directcolor, grayscale, pseudocolor, 967 staticcolor, staticgray, or truecolor for the 968 colormodel of this widget.""" 969 return self.tk.call('winfo', 'visual', self._w) 970 def winfo_visualid(self): 971 """Return the X identifier for the visual for this widget.""" 972 return self.tk.call('winfo', 'visualid', self._w) 973 def winfo_visualsavailable(self, includeids=0): 974 """Return a list of all visuals available for the screen 975 of this widget. 976 977 Each item in the list consists of a visual name (see winfo_visual), a 978 depth and if INCLUDEIDS=1 is given also the X identifier.""" 979 data = self.tk.split( 980 self.tk.call('winfo', 'visualsavailable', self._w, 981 includeids and 'includeids' or None)) 982 if type(data) is StringType: 983 data = [self.tk.split(data)] 984 return map(self.__winfo_parseitem, data) 985 def __winfo_parseitem(self, t): 986 """Internal function.""" 987 return t[:1] + tuple(map(self.__winfo_getint, t[1:])) 988 def __winfo_getint(self, x): 989 """Internal function.""" 990 return int(x, 0) 991 def winfo_vrootheight(self): 992 """Return the height of the virtual root window associated with this 993 widget in pixels. If there is no virtual root window return the 994 height of the screen.""" 995 return getint( 996 self.tk.call('winfo', 'vrootheight', self._w)) 997 def winfo_vrootwidth(self): 998 """Return the width of the virtual root window associated with this 999 widget in pixel. If there is no virtual root window return the 1000 width of the screen.""" 1001 return getint( 1002 self.tk.call('winfo', 'vrootwidth', self._w)) 1003 def winfo_vrootx(self): 1004 """Return the x offset of the virtual root relative to the root 1005 window of the screen of this widget.""" 1006 return getint( 1007 self.tk.call('winfo', 'vrootx', self._w)) 1008 def winfo_vrooty(self): 1009 """Return the y offset of the virtual root relative to the root 1010 window of the screen of this widget.""" 1011 return getint( 1012 self.tk.call('winfo', 'vrooty', self._w)) 1013 def winfo_width(self): 1014 """Return the width of this widget.""" 1015 return getint( 1016 self.tk.call('winfo', 'width', self._w)) 1017 def winfo_x(self): 1018 """Return the x coordinate of the upper left corner of this widget 1019 in the parent.""" 1020 return getint( 1021 self.tk.call('winfo', 'x', self._w)) 1022 def winfo_y(self): 1023 """Return the y coordinate of the upper left corner of this widget 1024 in the parent.""" 1025 return getint( 1026 self.tk.call('winfo', 'y', self._w)) 1027 def update(self): 1028 """Enter event loop until all pending events have been processed by Tcl.""" 1029 self.tk.call('update') 1030 def update_idletasks(self): 1031 """Enter event loop until all idle callbacks have been called. This 1032 will update the display of windows but not process events caused by 1033 the user.""" 1034 self.tk.call('update', 'idletasks') 1035 def bindtags(self, tagList=None): 1036 """Set or get the list of bindtags for this widget. 1037 1038 With no argument return the list of all bindtags associated with 1039 this widget. With a list of strings as argument the bindtags are 1040 set to this list. The bindtags determine in which order events are 1041 processed (see bind).""" 1042 if tagList is None: 1043 return self.tk.splitlist( 1044 self.tk.call('bindtags', self._w)) 1045 else: 1046 self.tk.call('bindtags', self._w, tagList) 1047 def _bind(self, what, sequence, func, add, needcleanup=1): 1048 """Internal function.""" 1049 if type(func) is StringType: 1050 self.tk.call(what + (sequence, func)) 1051 elif func: 1052 funcid = self._register(func, self._substitute, 1053 needcleanup) 1054 cmd = ('%sif {"[%s %s]" == "break"} break\n' 1055 % 1056 (add and '+' or '', 1057 funcid, self._subst_format_str)) 1058 self.tk.call(what + (sequence, cmd)) 1059 return funcid 1060 elif sequence: 1061 return self.tk.call(what + (sequence,)) 1062 else: 1063 return self.tk.splitlist(self.tk.call(what)) 1064 def bind(self, sequence=None, func=None, add=None): 1065 """Bind to this widget at event SEQUENCE a call to function FUNC. 1066 1067 SEQUENCE is a string of concatenated event 1068 patterns. An event pattern is of the form 1069 <MODIFIER-MODIFIER-TYPE-DETAIL> where MODIFIER is one 1070 of Control, Mod2, M2, Shift, Mod3, M3, Lock, Mod4, M4, 1071 Button1, B1, Mod5, M5 Button2, B2, Meta, M, Button3, 1072 B3, Alt, Button4, B4, Double, Button5, B5 Triple, 1073 Mod1, M1. TYPE is one of Activate, Enter, Map, 1074 ButtonPress, Button, Expose, Motion, ButtonRelease 1075 FocusIn, MouseWheel, Circulate, FocusOut, Property, 1076 Colormap, Gravity Reparent, Configure, KeyPress, Key, 1077 Unmap, Deactivate, KeyRelease Visibility, Destroy, 1078 Leave and DETAIL is the button number for ButtonPress, 1079 ButtonRelease and DETAIL is the Keysym for KeyPress and 1080 KeyRelease. Examples are 1081 <Control-Button-1> for pressing Control and mouse button 1 or 1082 <Alt-A> for pressing A and the Alt key (KeyPress can be omitted). 1083 An event pattern can also be a virtual event of the form 1084 <<AString>> where AString can be arbitrary. This 1085 event can be generated by event_generate. 1086 If events are concatenated they must appear shortly 1087 after each other. 1088 1089 FUNC will be called if the event sequence occurs with an 1090 instance of Event as argument. If the return value of FUNC is 1091 "break" no further bound function is invoked. 1092 1093 An additional boolean parameter ADD specifies whether FUNC will 1094 be called additionally to the other bound function or whether 1095 it will replace the previous function. 1096 1097 Bind will return an identifier to allow deletion of the bound function with 1098 unbind without memory leak. 1099 1100 If FUNC or SEQUENCE is omitted the bound function or list 1101 of bound events are returned.""" 1102 1103 return self._bind(('bind', self._w), sequence, func, add) 1104 def unbind(self, sequence, funcid=None): 1105 """Unbind for this widget for event SEQUENCE the 1106 function identified with FUNCID.""" 1107 self.tk.call('bind', self._w, sequence, '') 1108 if funcid: 1109 self.deletecommand(funcid) 1110 def bind_all(self, sequence=None, func=None, add=None): 1111 """Bind to all widgets at an event SEQUENCE a call to function FUNC. 1112 An additional boolean parameter ADD specifies whether FUNC will 1113 be called additionally to the other bound function or whether 1114 it will replace the previous function. See bind for the return value.""" 1115 return self._bind(('bind', 'all'), sequence, func, add, 0) 1116 def unbind_all(self, sequence): 1117 """Unbind for all widgets for event SEQUENCE all functions.""" 1118 self.tk.call('bind', 'all' , sequence, '') 1119 def bind_class(self, className, sequence=None, func=None, add=None): 1120 1121 """Bind to widgets with bindtag CLASSNAME at event 1122 SEQUENCE a call of function FUNC. An additional 1123 boolean parameter ADD specifies whether FUNC will be 1124 called additionally to the other bound function or 1125 whether it will replace the previous function. See bind for 1126 the return value.""" 1127 1128 return self._bind(('bind', className), sequence, func, add, 0) 1129 def unbind_class(self, className, sequence): 1130 """Unbind for all widgets with bindtag CLASSNAME for event SEQUENCE 1131 all functions.""" 1132 self.tk.call('bind', className , sequence, '') 1133 def mainloop(self, n=0): 1134 """Call the mainloop of Tk.""" 1135 self.tk.mainloop(n) 1136 def quit(self): 1137 """Quit the Tcl interpreter. All widgets will be destroyed.""" 1138 self.tk.quit() 1139 def _getints(self, string): 1140 """Internal function.""" 1141 if string: 1142 return tuple(map(getint, self.tk.splitlist(string))) 1143 def _getdoubles(self, string): 1144 """Internal function.""" 1145 if string: 1146 return tuple(map(getdouble, self.tk.splitlist(string))) 1147 def _getboolean(self, string): 1148 """Internal function.""" 1149 if string: 1150 return self.tk.getboolean(string) 1151 def _displayof(self, displayof): 1152 """Internal function.""" 1153 if displayof: 1154 return ('-displayof', displayof) 1155 if displayof is None: 1156 return ('-displayof', self._w) 1157 return () 1158 @property 1159 def _windowingsystem(self): 1160 """Internal function.""" 1161 try: 1162 return self._root()._windowingsystem_cached 1163 except AttributeError: 1164 ws = self._root()._windowingsystem_cached = \ 1165 self.tk.call('tk', 'windowingsystem') 1166 return ws 1167 def _options(self, cnf, kw = None): 1168 """Internal function.""" 1169 if kw: 1170 cnf = _cnfmerge((cnf, kw)) 1171 else: 1172 cnf = _cnfmerge(cnf) 1173 res = () 1174 for k, v in cnf.items(): 1175 if v is not None: 1176 if k[-1] == '_': k = k[:-1] 1177 if hasattr(v, '__call__'): 1178 v = self._register(v) 1179 elif isinstance(v, (tuple, list)): 1180 nv = [] 1181 for item in v: 1182 if not isinstance(item, (basestring, int, long)): 1183 break 1184 elif isinstance(item, (int, long)): 1185 nv.append('%d' % item) 1186 else: 1187 # format it to proper Tcl code if it contains space 1188 nv.append(_stringify(item)) 1189 else: 1190 v = ' '.join(nv) 1191 res = res + ('-'+k, v) 1192 return res 1193 def nametowidget(self, name): 1194 """Return the Tkinter instance of a widget identified by 1195 its Tcl name NAME.""" 1196 name = str(name).split('.') 1197 w = self 1198 1199 if not name[0]: 1200 w = w._root() 1201 name = name[1:] 1202 1203 for n in name: 1204 if not n: 1205 break 1206 w = w.children[n] 1207 1208 return w 1209 _nametowidget = nametowidget 1210 def _register(self, func, subst=None, needcleanup=1): 1211 """Return a newly created Tcl function. If this 1212 function is called, the Python function FUNC will 1213 be executed. An optional function SUBST can 1214 be given which will be executed before FUNC.""" 1215 f = CallWrapper(func, subst, self).__call__ 1216 name = repr(id(f)) 1217 try: 1218 func = func.im_func 1219 except AttributeError: 1220 pass 1221 try: 1222 name = name + func.__name__ 1223 except AttributeError: 1224 pass 1225 self.tk.createcommand(name, f) 1226 if needcleanup: 1227 if self._tclCommands is None: 1228 self._tclCommands = [] 1229 self._tclCommands.append(name) 1230 return name 1231 register = _register 1232 def _root(self): 1233 """Internal function.""" 1234 w = self 1235 while w.master: w = w.master 1236 return w 1237 _subst_format = ('%#', '%b', '%f', '%h', '%k', 1238 '%s', '%t', '%w', '%x', '%y', 1239 '%A', '%E', '%K', '%N', '%W', '%T', '%X', '%Y', '%D') 1240 _subst_format_str = " ".join(_subst_format) 1241 def _substitute(self, *args): 1242 """Internal function.""" 1243 if len(args) != len(self._subst_format): return args 1244 getboolean = self.tk.getboolean 1245 1246 getint = int 1247 def getint_event(s): 1248 """Tk changed behavior in 8.4.2, returning "??" rather more often.""" 1249 try: 1250 return int(s) 1251 except ValueError: 1252 return s 1253 1254 nsign, b, f, h, k, s, t, w, x, y, A, E, K, N, W, T, X, Y, D = args 1255 # Missing: (a, c, d, m, o, v, B, R) 1256 e = Event() 1257 # serial field: valid for all events 1258 # number of button: ButtonPress and ButtonRelease events only 1259 # height field: Configure, ConfigureRequest, Create, 1260 # ResizeRequest, and Expose events only 1261 # keycode field: KeyPress and KeyRelease events only 1262 # time field: "valid for events that contain a time field" 1263 # width field: Configure, ConfigureRequest, Create, ResizeRequest, 1264 # and Expose events only 1265 # x field: "valid for events that contain an x field" 1266 # y field: "valid for events that contain a y field" 1267 # keysym as decimal: KeyPress and KeyRelease events only 1268 # x_root, y_root fields: ButtonPress, ButtonRelease, KeyPress, 1269 # KeyRelease, and Motion events 1270 e.serial = getint(nsign) 1271 e.num = getint_event(b) 1272 try: e.focus = getboolean(f) 1273 except TclError: pass 1274 e.height = getint_event(h) 1275 e.keycode = getint_event(k) 1276 e.state = getint_event(s) 1277 e.time = getint_event(t) 1278 e.width = getint_event(w) 1279 e.x = getint_event(x) 1280 e.y = getint_event(y) 1281 e.char = A 1282 try: e.send_event = getboolean(E) 1283 except TclError: pass 1284 e.keysym = K 1285 e.keysym_num = getint_event(N) 1286 e.type = T 1287 try: 1288 e.widget = self._nametowidget(W) 1289 except KeyError: 1290 e.widget = W 1291 e.x_root = getint_event(X) 1292 e.y_root = getint_event(Y) 1293 try: 1294 e.delta = getint(D) 1295 except ValueError: 1296 e.delta = 0 1297 return (e,) 1298 def _report_exception(self): 1299 """Internal function.""" 1300 import sys 1301 exc, val, tb = sys.exc_type, sys.exc_value, sys.exc_traceback 1302 root = self._root() 1303 root.report_callback_exception(exc, val, tb) 1304 1305 def _getconfigure(self, *args): 1306 """Call Tcl configure command and return the result as a dict.""" 1307 cnf = {} 1308 for x in self.tk.splitlist(self.tk.call(*args)): 1309 x = self.tk.splitlist(x) 1310 cnf[x[0][1:]] = (x[0][1:],) + x[1:] 1311 return cnf 1312 1313 def _getconfigure1(self, *args): 1314 x = self.tk.splitlist(self.tk.call(*args)) 1315 return (x[0][1:],) + x[1:] 1316 1317 def _configure(self, cmd, cnf, kw): 1318 """Internal function.""" 1319 if kw: 1320 cnf = _cnfmerge((cnf, kw)) 1321 elif cnf: 1322 cnf = _cnfmerge(cnf) 1323 if cnf is None: 1324 return self._getconfigure(_flatten((self._w, cmd))) 1325 if type(cnf) is StringType: 1326 return self._getconfigure1(_flatten((self._w, cmd, '-'+cnf))) 1327 self.tk.call(_flatten((self._w, cmd)) + self._options(cnf)) 1328 # These used to be defined in Widget: 1329 def configure(self, cnf=None, **kw): 1330 """Configure resources of a widget. 1331 1332 The values for resources are specified as keyword 1333 arguments. To get an overview about 1334 the allowed keyword arguments call the method keys. 1335 """ 1336 return self._configure('configure', cnf, kw) 1337 config = configure 1338 def cget(self, key): 1339 """Return the resource value for a KEY given as string.""" 1340 return self.tk.call(self._w, 'cget', '-' + key) 1341 __getitem__ = cget 1342 def __setitem__(self, key, value): 1343 self.configure({key: value}) 1344 def __contains__(self, key): 1345 raise TypeError("Tkinter objects don't support 'in' tests.") 1346 def keys(self): 1347 """Return a list of all resource names of this widget.""" 1348 splitlist = self.tk.splitlist 1349 return [splitlist(x)[0][1:] for x in 1350 splitlist(self.tk.call(self._w, 'configure'))] 1351 def __str__(self): 1352 """Return the window path name of this widget.""" 1353 return self._w 1354 # Pack methods that apply to the master 1355 _noarg_ = ['_noarg_'] 1356 def pack_propagate(self, flag=_noarg_): 1357 """Set or get the status for propagation of geometry information. 1358 1359 A boolean argument specifies whether the geometry information 1360 of the slaves will determine the size of this widget. If no argument 1361 is given the current setting will be returned. 1362 """ 1363 if flag is Misc._noarg_: 1364 return self._getboolean(self.tk.call( 1365 'pack', 'propagate', self._w)) 1366 else: 1367 self.tk.call('pack', 'propagate', self._w, flag) 1368 propagate = pack_propagate 1369 def pack_slaves(self): 1370 """Return a list of all slaves of this widget 1371 in its packing order.""" 1372 return map(self._nametowidget, 1373 self.tk.splitlist( 1374 self.tk.call('pack', 'slaves', self._w))) 1375 slaves = pack_slaves 1376 # Place method that applies to the master 1377 def place_slaves(self): 1378 """Return a list of all slaves of this widget 1379 in its packing order.""" 1380 return map(self._nametowidget, 1381 self.tk.splitlist( 1382 self.tk.call( 1383 'place', 'slaves', self._w))) 1384 # Grid methods that apply to the master 1385 def grid_bbox(self, column=None, row=None, col2=None, row2=None): 1386 """Return a tuple of integer coordinates for the bounding 1387 box of this widget controlled by the geometry manager grid. 1388 1389 If COLUMN, ROW is given the bounding box applies from 1390 the cell with row and column 0 to the specified 1391 cell. If COL2 and ROW2 are given the bounding box 1392 starts at that cell. 1393 1394 The returned integers specify the offset of the upper left 1395 corner in the master widget and the width and height. 1396 """ 1397 args = ('grid', 'bbox', self._w) 1398 if column is not None and row is not None: 1399 args = args + (column, row) 1400 if col2 is not None and row2 is not None: 1401 args = args + (col2, row2) 1402 return self._getints(self.tk.call(*args)) or None 1403 1404 bbox = grid_bbox 1405 1406 def _gridconvvalue(self, value): 1407 if isinstance(value, (str, _tkinter.Tcl_Obj)): 1408 try: 1409 svalue = str(value) 1410 if not svalue: 1411 return None 1412 elif '.' in svalue: 1413 return getdouble(svalue) 1414 else: 1415 return getint(svalue) 1416 except ValueError: 1417 pass 1418 return value 1419 1420 def _grid_configure(self, command, index, cnf, kw): 1421 """Internal function.""" 1422 if type(cnf) is StringType and not kw: 1423 if cnf[-1:] == '_': 1424 cnf = cnf[:-1] 1425 if cnf[:1] != '-': 1426 cnf = '-'+cnf 1427 options = (cnf,) 1428 else: 1429 options = self._options(cnf, kw) 1430 if not options: 1431 return _splitdict( 1432 self.tk, 1433 self.tk.call('grid', command, self._w, index), 1434 conv=self._gridconvvalue) 1435 res = self.tk.call( 1436 ('grid', command, self._w, index) 1437 + options) 1438 if len(options) == 1: 1439 return self._gridconvvalue(res) 1440 1441 def grid_columnconfigure(self, index, cnf={}, **kw): 1442 """Configure column INDEX of a grid. 1443 1444 Valid resources are minsize (minimum size of the column), 1445 weight (how much does additional space propagate to this column) 1446 and pad (how much space to let additionally).""" 1447 return self._grid_configure('columnconfigure', index, cnf, kw) 1448 columnconfigure = grid_columnconfigure 1449 def grid_location(self, x, y): 1450 """Return a tuple of column and row which identify the cell 1451 at which the pixel at position X and Y inside the master 1452 widget is located.""" 1453 return self._getints( 1454 self.tk.call( 1455 'grid', 'location', self._w, x, y)) or None 1456 def grid_propagate(self, flag=_noarg_): 1457 """Set or get the status for propagation of geometry information. 1458 1459 A boolean argument specifies whether the geometry information 1460 of the slaves will determine the size of this widget. If no argument 1461 is given, the current setting will be returned. 1462 """ 1463 if flag is Misc._noarg_: 1464 return self._getboolean(self.tk.call( 1465 'grid', 'propagate', self._w)) 1466 else: 1467 self.tk.call('grid', 'propagate', self._w, flag) 1468 def grid_rowconfigure(self, index, cnf={}, **kw): 1469 """Configure row INDEX of a grid. 1470 1471 Valid resources are minsize (minimum size of the row), 1472 weight (how much does additional space propagate to this row) 1473 and pad (how much space to let additionally).""" 1474 return self._grid_configure('rowconfigure', index, cnf, kw) 1475 rowconfigure = grid_rowconfigure 1476 def grid_size(self): 1477 """Return a tuple of the number of column and rows in the grid.""" 1478 return self._getints( 1479 self.tk.call('grid', 'size', self._w)) or None 1480 size = grid_size 1481 def grid_slaves(self, row=None, column=None): 1482 """Return a list of all slaves of this widget 1483 in its packing order.""" 1484 args = () 1485 if row is not None: 1486 args = args + ('-row', row) 1487 if column is not None: 1488 args = args + ('-column', column) 1489 return map(self._nametowidget, 1490 self.tk.splitlist(self.tk.call( 1491 ('grid', 'slaves', self._w) + args))) 1492 1493 # Support for the "event" command, new in Tk 4.2. 1494 # By Case Roole. 1495 1496 def event_add(self, virtual, *sequences): 1497 """Bind a virtual event VIRTUAL (of the form <<Name>>) 1498 to an event SEQUENCE such that the virtual event is triggered 1499 whenever SEQUENCE occurs.""" 1500 args = ('event', 'add', virtual) + sequences 1501 self.tk.call(args) 1502 1503 def event_delete(self, virtual, *sequences): 1504 """Unbind a virtual event VIRTUAL from SEQUENCE.""" 1505 args = ('event', 'delete', virtual) + sequences 1506 self.tk.call(args) 1507 1508 def event_generate(self, sequence, **kw): 1509 """Generate an event SEQUENCE. Additional 1510 keyword arguments specify parameter of the event 1511 (e.g. x, y, rootx, rooty).""" 1512 args = ('event', 'generate', self._w, sequence) 1513 for k, v in kw.items(): 1514 args = args + ('-%s' % k, str(v)) 1515 self.tk.call(args) 1516 1517 def event_info(self, virtual=None): 1518 """Return a list of all virtual events or the information 1519 about the SEQUENCE bound to the virtual event VIRTUAL.""" 1520 return self.tk.splitlist( 1521 self.tk.call('event', 'info', virtual)) 1522 1523 # Image related commands 1524 1525 def image_names(self): 1526 """Return a list of all existing image names.""" 1527 return self.tk.splitlist(self.tk.call('image', 'names')) 1528 1529 def image_types(self): 1530 """Return a list of all available image types (e.g. photo bitmap).""" 1531 return self.tk.splitlist(self.tk.call('image', 'types')) 1532 1533 1534class CallWrapper: 1535 """Internal class. Stores function to call when some user 1536 defined Tcl function is called e.g. after an event occurred.""" 1537 def __init__(self, func, subst, widget): 1538 """Store FUNC, SUBST and WIDGET as members.""" 1539 self.func = func 1540 self.subst = subst 1541 self.widget = widget 1542 def __call__(self, *args): 1543 """Apply first function SUBST to arguments, than FUNC.""" 1544 try: 1545 if self.subst: 1546 args = self.subst(*args) 1547 return self.func(*args) 1548 except SystemExit, msg: 1549 raise SystemExit, msg 1550 except: 1551 self.widget._report_exception() 1552 1553 1554class XView: 1555 """Mix-in class for querying and changing the horizontal position 1556 of a widget's window.""" 1557 1558 def xview(self, *args): 1559 """Query and change the horizontal position of the view.""" 1560 res = self.tk.call(self._w, 'xview', *args) 1561 if not args: 1562 return self._getdoubles(res) 1563 1564 def xview_moveto(self, fraction): 1565 """Adjusts the view in the window so that FRACTION of the 1566 total width of the canvas is off-screen to the left.""" 1567 self.tk.call(self._w, 'xview', 'moveto', fraction) 1568 1569 def xview_scroll(self, number, what): 1570 """Shift the x-view according to NUMBER which is measured in "units" 1571 or "pages" (WHAT).""" 1572 self.tk.call(self._w, 'xview', 'scroll', number, what) 1573 1574 1575class YView: 1576 """Mix-in class for querying and changing the vertical position 1577 of a widget's window.""" 1578 1579 def yview(self, *args): 1580 """Query and change the vertical position of the view.""" 1581 res = self.tk.call(self._w, 'yview', *args) 1582 if not args: 1583 return self._getdoubles(res) 1584 1585 def yview_moveto(self, fraction): 1586 """Adjusts the view in the window so that FRACTION of the 1587 total height of the canvas is off-screen to the top.""" 1588 self.tk.call(self._w, 'yview', 'moveto', fraction) 1589 1590 def yview_scroll(self, number, what): 1591 """Shift the y-view according to NUMBER which is measured in 1592 "units" or "pages" (WHAT).""" 1593 self.tk.call(self._w, 'yview', 'scroll', number, what) 1594 1595 1596class Wm: 1597 """Provides functions for the communication with the window manager.""" 1598 1599 def wm_aspect(self, 1600 minNumer=None, minDenom=None, 1601 maxNumer=None, maxDenom=None): 1602 """Instruct the window manager to set the aspect ratio (width/height) 1603 of this widget to be between MINNUMER/MINDENOM and MAXNUMER/MAXDENOM. Return a tuple 1604 of the actual values if no argument is given.""" 1605 return self._getints( 1606 self.tk.call('wm', 'aspect', self._w, 1607 minNumer, minDenom, 1608 maxNumer, maxDenom)) 1609 aspect = wm_aspect 1610 1611 def wm_attributes(self, *args): 1612 """This subcommand returns or sets platform specific attributes 1613 1614 The first form returns a list of the platform specific flags and 1615 their values. The second form returns the value for the specific 1616 option. The third form sets one or more of the values. The values 1617 are as follows: 1618 1619 On Windows, -disabled gets or sets whether the window is in a 1620 disabled state. -toolwindow gets or sets the style of the window 1621 to toolwindow (as defined in the MSDN). -topmost gets or sets 1622 whether this is a topmost window (displays above all other 1623 windows). 1624 1625 On Macintosh, XXXXX 1626 1627 On Unix, there are currently no special attribute values. 1628 """ 1629 args = ('wm', 'attributes', self._w) + args 1630 return self.tk.call(args) 1631 attributes=wm_attributes 1632 1633 def wm_client(self, name=None): 1634 """Store NAME in WM_CLIENT_MACHINE property of this widget. Return 1635 current value.""" 1636 return self.tk.call('wm', 'client', self._w, name) 1637 client = wm_client 1638 def wm_colormapwindows(self, *wlist): 1639 """Store list of window names (WLIST) into WM_COLORMAPWINDOWS property 1640 of this widget. This list contains windows whose colormaps differ from their 1641 parents. Return current list of widgets if WLIST is empty.""" 1642 if len(wlist) > 1: 1643 wlist = (wlist,) # Tk needs a list of windows here 1644 args = ('wm', 'colormapwindows', self._w) + wlist 1645 if wlist: 1646 self.tk.call(args) 1647 else: 1648 return map(self._nametowidget, self.tk.splitlist(self.tk.call(args))) 1649 colormapwindows = wm_colormapwindows 1650 def wm_command(self, value=None): 1651 """Store VALUE in WM_COMMAND property. It is the command 1652 which shall be used to invoke the application. Return current 1653 command if VALUE is None.""" 1654 return self.tk.call('wm', 'command', self._w, value) 1655 command = wm_command 1656 def wm_deiconify(self): 1657 """Deiconify this widget. If it was never mapped it will not be mapped. 1658 On Windows it will raise this widget and give it the focus.""" 1659 return self.tk.call('wm', 'deiconify', self._w) 1660 deiconify = wm_deiconify 1661 def wm_focusmodel(self, model=None): 1662 """Set focus model to MODEL. "active" means that this widget will claim 1663 the focus itself, "passive" means that the window manager shall give 1664 the focus. Return current focus model if MODEL is None.""" 1665 return self.tk.call('wm', 'focusmodel', self._w, model) 1666 focusmodel = wm_focusmodel 1667 def wm_frame(self): 1668 """Return identifier for decorative frame of this widget if present.""" 1669 return self.tk.call('wm', 'frame', self._w) 1670 frame = wm_frame 1671 def wm_geometry(self, newGeometry=None): 1672 """Set geometry to NEWGEOMETRY of the form =widthxheight+x+y. Return 1673 current value if None is given.""" 1674 return self.tk.call('wm', 'geometry', self._w, newGeometry) 1675 geometry = wm_geometry 1676 def wm_grid(self, 1677 baseWidth=None, baseHeight=None, 1678 widthInc=None, heightInc=None): 1679 """Instruct the window manager that this widget shall only be 1680 resized on grid boundaries. WIDTHINC and HEIGHTINC are the width and 1681 height of a grid unit in pixels. BASEWIDTH and BASEHEIGHT are the 1682 number of grid units requested in Tk_GeometryRequest.""" 1683 return self._getints(self.tk.call( 1684 'wm', 'grid', self._w, 1685 baseWidth, baseHeight, widthInc, heightInc)) 1686 grid = wm_grid 1687 def wm_group(self, pathName=None): 1688 """Set the group leader widgets for related widgets to PATHNAME. Return 1689 the group leader of this widget if None is given.""" 1690 return self.tk.call('wm', 'group', self._w, pathName) 1691 group = wm_group 1692 def wm_iconbitmap(self, bitmap=None, default=None): 1693 """Set bitmap for the iconified widget to BITMAP. Return 1694 the bitmap if None is given. 1695 1696 Under Windows, the DEFAULT parameter can be used to set the icon 1697 for the widget and any descendents that don't have an icon set 1698 explicitly. DEFAULT can be the relative path to a .ico file 1699 (example: root.iconbitmap(default='myicon.ico') ). See Tk 1700 documentation for more information.""" 1701 if default: 1702 return self.tk.call('wm', 'iconbitmap', self._w, '-default', default) 1703 else: 1704 return self.tk.call('wm', 'iconbitmap', self._w, bitmap) 1705 iconbitmap = wm_iconbitmap 1706 def wm_iconify(self): 1707 """Display widget as icon.""" 1708 return self.tk.call('wm', 'iconify', self._w) 1709 iconify = wm_iconify 1710 def wm_iconmask(self, bitmap=None): 1711 """Set mask for the icon bitmap of this widget. Return the 1712 mask if None is given.""" 1713 return self.tk.call('wm', 'iconmask', self._w, bitmap) 1714 iconmask = wm_iconmask 1715 def wm_iconname(self, newName=None): 1716 """Set the name of the icon for this widget. Return the name if 1717 None is given.""" 1718 return self.tk.call('wm', 'iconname', self._w, newName) 1719 iconname = wm_iconname 1720 def wm_iconposition(self, x=None, y=None): 1721 """Set the position of the icon of this widget to X and Y. Return 1722 a tuple of the current values of X and X if None is given.""" 1723 return self._getints(self.tk.call( 1724 'wm', 'iconposition', self._w, x, y)) 1725 iconposition = wm_iconposition 1726 def wm_iconwindow(self, pathName=None): 1727 """Set widget PATHNAME to be displayed instead of icon. Return the current 1728 value if None is given.""" 1729 return self.tk.call('wm', 'iconwindow', self._w, pathName) 1730 iconwindow = wm_iconwindow 1731 def wm_maxsize(self, width=None, height=None): 1732 """Set max WIDTH and HEIGHT for this widget. If the window is gridded 1733 the values are given in grid units. Return the current values if None 1734 is given.""" 1735 return self._getints(self.tk.call( 1736 'wm', 'maxsize', self._w, width, height)) 1737 maxsize = wm_maxsize 1738 def wm_minsize(self, width=None, height=None): 1739 """Set min WIDTH and HEIGHT for this widget. If the window is gridded 1740 the values are given in grid units. Return the current values if None 1741 is given.""" 1742 return self._getints(self.tk.call( 1743 'wm', 'minsize', self._w, width, height)) 1744 minsize = wm_minsize 1745 def wm_overrideredirect(self, boolean=None): 1746 """Instruct the window manager to ignore this widget 1747 if BOOLEAN is given with 1. Return the current value if None 1748 is given.""" 1749 return self._getboolean(self.tk.call( 1750 'wm', 'overrideredirect', self._w, boolean)) 1751 overrideredirect = wm_overrideredirect 1752 def wm_positionfrom(self, who=None): 1753 """Instruct the window manager that the position of this widget shall 1754 be defined by the user if WHO is "user", and by its own policy if WHO is 1755 "program".""" 1756 return self.tk.call('wm', 'positionfrom', self._w, who) 1757 positionfrom = wm_positionfrom 1758 def wm_protocol(self, name=None, func=None): 1759 """Bind function FUNC to command NAME for this widget. 1760 Return the function bound to NAME if None is given. NAME could be 1761 e.g. "WM_SAVE_YOURSELF" or "WM_DELETE_WINDOW".""" 1762 if hasattr(func, '__call__'): 1763 command = self._register(func) 1764 else: 1765 command = func 1766 return self.tk.call( 1767 'wm', 'protocol', self._w, name, command) 1768 protocol = wm_protocol 1769 def wm_resizable(self, width=None, height=None): 1770 """Instruct the window manager whether this width can be resized 1771 in WIDTH or HEIGHT. Both values are boolean values.""" 1772 return self.tk.call('wm', 'resizable', self._w, width, height) 1773 resizable = wm_resizable 1774 def wm_sizefrom(self, who=None): 1775 """Instruct the window manager that the size of this widget shall 1776 be defined by the user if WHO is "user", and by its own policy if WHO is 1777 "program".""" 1778 return self.tk.call('wm', 'sizefrom', self._w, who) 1779 sizefrom = wm_sizefrom 1780 def wm_state(self, newstate=None): 1781 """Query or set the state of this widget as one of normal, icon, 1782 iconic (see wm_iconwindow), withdrawn, or zoomed (Windows only).""" 1783 return self.tk.call('wm', 'state', self._w, newstate) 1784 state = wm_state 1785 def wm_title(self, string=None): 1786 """Set the title of this widget.""" 1787 return self.tk.call('wm', 'title', self._w, string) 1788 title = wm_title 1789 def wm_transient(self, master=None): 1790 """Instruct the window manager that this widget is transient 1791 with regard to widget MASTER.""" 1792 return self.tk.call('wm', 'transient', self._w, master) 1793 transient = wm_transient 1794 def wm_withdraw(self): 1795 """Withdraw this widget from the screen such that it is unmapped 1796 and forgotten by the window manager. Re-draw it with wm_deiconify.""" 1797 return self.tk.call('wm', 'withdraw', self._w) 1798 withdraw = wm_withdraw 1799 1800 1801class Tk(Misc, Wm): 1802 """Toplevel widget of Tk which represents mostly the main window 1803 of an application. It has an associated Tcl interpreter.""" 1804 _w = '.' 1805 def __init__(self, screenName=None, baseName=None, className='Tk', 1806 useTk=1, sync=0, use=None): 1807 """Return a new Toplevel widget on screen SCREENNAME. A new Tcl interpreter will 1808 be created. BASENAME will be used for the identification of the profile file (see 1809 readprofile). 1810 It is constructed from sys.argv[0] without extensions if None is given. CLASSNAME 1811 is the name of the widget class.""" 1812 self.master = None 1813 self.children = {} 1814 self._tkloaded = 0 1815 # to avoid recursions in the getattr code in case of failure, we 1816 # ensure that self.tk is always _something_. 1817 self.tk = None 1818 if baseName is None: 1819 import os 1820 baseName = os.path.basename(sys.argv[0]) 1821 baseName, ext = os.path.splitext(baseName) 1822 if ext not in ('.py', '.pyc', '.pyo'): 1823 baseName = baseName + ext 1824 interactive = 0 1825 self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use) 1826 if useTk: 1827 self._loadtk() 1828 if not sys.flags.ignore_environment: 1829 # Issue #16248: Honor the -E flag to avoid code injection. 1830 self.readprofile(baseName, className) 1831 def loadtk(self): 1832 if not self._tkloaded: 1833 self.tk.loadtk() 1834 self._loadtk() 1835 def _loadtk(self): 1836 self._tkloaded = 1 1837 global _default_root 1838 # Version sanity checks 1839 tk_version = self.tk.getvar('tk_version') 1840 if tk_version != _tkinter.TK_VERSION: 1841 raise RuntimeError, \ 1842 "tk.h version (%s) doesn't match libtk.a version (%s)" \ 1843 % (_tkinter.TK_VERSION, tk_version) 1844 # Under unknown circumstances, tcl_version gets coerced to float 1845 tcl_version = str(self.tk.getvar('tcl_version')) 1846 if tcl_version != _tkinter.TCL_VERSION: 1847 raise RuntimeError, \ 1848 "tcl.h version (%s) doesn't match libtcl.a version (%s)" \ 1849 % (_tkinter.TCL_VERSION, tcl_version) 1850 if TkVersion < 4.0: 1851 raise RuntimeError, \ 1852 "Tk 4.0 or higher is required; found Tk %s" \ 1853 % str(TkVersion) 1854 # Create and register the tkerror and exit commands 1855 # We need to inline parts of _register here, _ register 1856 # would register differently-named commands. 1857 if self._tclCommands is None: 1858 self._tclCommands = [] 1859 self.tk.createcommand('tkerror', _tkerror) 1860 self.tk.createcommand('exit', _exit) 1861 self._tclCommands.append('tkerror') 1862 self._tclCommands.append('exit') 1863 if _support_default_root and not _default_root: 1864 _default_root = self 1865 self.protocol("WM_DELETE_WINDOW", self.destroy) 1866 def destroy(self): 1867 """Destroy this and all descendants widgets. This will 1868 end the application of this Tcl interpreter.""" 1869 for c in self.children.values(): c.destroy() 1870 self.tk.call('destroy', self._w) 1871 Misc.destroy(self) 1872 global _default_root 1873 if _support_default_root and _default_root is self: 1874 _default_root = None 1875 def readprofile(self, baseName, className): 1876 """Internal function. It reads BASENAME.tcl and CLASSNAME.tcl into 1877 the Tcl Interpreter and calls execfile on BASENAME.py and CLASSNAME.py if 1878 such a file exists in the home directory.""" 1879 import os 1880 if 'HOME' in os.environ: home = os.environ['HOME'] 1881 else: home = os.curdir 1882 class_tcl = os.path.join(home, '.%s.tcl' % className) 1883 class_py = os.path.join(home, '.%s.py' % className) 1884 base_tcl = os.path.join(home, '.%s.tcl' % baseName) 1885 base_py = os.path.join(home, '.%s.py' % baseName) 1886 dir = {'self': self} 1887 exec 'from Tkinter import *' in dir 1888 if os.path.isfile(class_tcl): 1889 self.tk.call('source', class_tcl) 1890 if os.path.isfile(class_py): 1891 execfile(class_py, dir) 1892 if os.path.isfile(base_tcl): 1893 self.tk.call('source', base_tcl) 1894 if os.path.isfile(base_py): 1895 execfile(base_py, dir) 1896 def report_callback_exception(self, exc, val, tb): 1897 """Report callback exception on sys.stderr. 1898 1899 Applications may want to override this internal function, and 1900 should when sys.stderr is None.""" 1901 import traceback, sys 1902 print >>sys.stderr, "Exception in Tkinter callback" 1903 sys.last_type = exc 1904 sys.last_value = val 1905 sys.last_traceback = tb 1906 traceback.print_exception(exc, val, tb) 1907 def __getattr__(self, attr): 1908 "Delegate attribute access to the interpreter object" 1909 return getattr(self.tk, attr) 1910 1911# Ideally, the classes Pack, Place and Grid disappear, the 1912# pack/place/grid methods are defined on the Widget class, and 1913# everybody uses w.pack_whatever(...) instead of Pack.whatever(w, 1914# ...), with pack(), place() and grid() being short for 1915# pack_configure(), place_configure() and grid_columnconfigure(), and 1916# forget() being short for pack_forget(). As a practical matter, I'm 1917# afraid that there is too much code out there that may be using the 1918# Pack, Place or Grid class, so I leave them intact -- but only as 1919# backwards compatibility features. Also note that those methods that 1920# take a master as argument (e.g. pack_propagate) have been moved to 1921# the Misc class (which now incorporates all methods common between 1922# toplevel and interior widgets). Again, for compatibility, these are 1923# copied into the Pack, Place or Grid class. 1924 1925 1926def Tcl(screenName=None, baseName=None, className='Tk', useTk=0): 1927 return Tk(screenName, baseName, className, useTk) 1928 1929class Pack: 1930 """Geometry manager Pack. 1931 1932 Base class to use the methods pack_* in every widget.""" 1933 def pack_configure(self, cnf={}, **kw): 1934 """Pack a widget in the parent widget. Use as options: 1935 after=widget - pack it after you have packed widget 1936 anchor=NSEW (or subset) - position widget according to 1937 given direction 1938 before=widget - pack it before you will pack widget 1939 expand=bool - expand widget if parent size grows 1940 fill=NONE or X or Y or BOTH - fill widget if widget grows 1941 in=master - use master to contain this widget 1942 in_=master - see 'in' option description 1943 ipadx=amount - add internal padding in x direction 1944 ipady=amount - add internal padding in y direction 1945 padx=amount - add padding in x direction 1946 pady=amount - add padding in y direction 1947 side=TOP or BOTTOM or LEFT or RIGHT - where to add this widget. 1948 """ 1949 self.tk.call( 1950 ('pack', 'configure', self._w) 1951 + self._options(cnf, kw)) 1952 pack = configure = config = pack_configure 1953 def pack_forget(self): 1954 """Unmap this widget and do not use it for the packing order.""" 1955 self.tk.call('pack', 'forget', self._w) 1956 forget = pack_forget 1957 def pack_info(self): 1958 """Return information about the packing options 1959 for this widget.""" 1960 d = _splitdict(self.tk, self.tk.call('pack', 'info', self._w)) 1961 if 'in' in d: 1962 d['in'] = self.nametowidget(d['in']) 1963 return d 1964 info = pack_info 1965 propagate = pack_propagate = Misc.pack_propagate 1966 slaves = pack_slaves = Misc.pack_slaves 1967 1968class Place: 1969 """Geometry manager Place. 1970 1971 Base class to use the methods place_* in every widget.""" 1972 def place_configure(self, cnf={}, **kw): 1973 """Place a widget in the parent widget. Use as options: 1974 in=master - master relative to which the widget is placed 1975 in_=master - see 'in' option description 1976 x=amount - locate anchor of this widget at position x of master 1977 y=amount - locate anchor of this widget at position y of master 1978 relx=amount - locate anchor of this widget between 0.0 and 1.0 1979 relative to width of master (1.0 is right edge) 1980 rely=amount - locate anchor of this widget between 0.0 and 1.0 1981 relative to height of master (1.0 is bottom edge) 1982 anchor=NSEW (or subset) - position anchor according to given direction 1983 width=amount - width of this widget in pixel 1984 height=amount - height of this widget in pixel 1985 relwidth=amount - width of this widget between 0.0 and 1.0 1986 relative to width of master (1.0 is the same width 1987 as the master) 1988 relheight=amount - height of this widget between 0.0 and 1.0 1989 relative to height of master (1.0 is the same 1990 height as the master) 1991 bordermode="inside" or "outside" - whether to take border width of 1992 master widget into account 1993 """ 1994 self.tk.call( 1995 ('place', 'configure', self._w) 1996 + self._options(cnf, kw)) 1997 place = configure = config = place_configure 1998 def place_forget(self): 1999 """Unmap this widget.""" 2000 self.tk.call('place', 'forget', self._w) 2001 forget = place_forget 2002 def place_info(self): 2003 """Return information about the placing options 2004 for this widget.""" 2005 d = _splitdict(self.tk, self.tk.call('place', 'info', self._w)) 2006 if 'in' in d: 2007 d['in'] = self.nametowidget(d['in']) 2008 return d 2009 info = place_info 2010 slaves = place_slaves = Misc.place_slaves 2011 2012class Grid: 2013 """Geometry manager Grid. 2014 2015 Base class to use the methods grid_* in every widget.""" 2016 # Thanks to Masazumi Yoshikawa (yosikawa@isi.edu) 2017 def grid_configure(self, cnf={}, **kw): 2018 """Position a widget in the parent widget in a grid. Use as options: 2019 column=number - use cell identified with given column (starting with 0) 2020 columnspan=number - this widget will span several columns 2021 in=master - use master to contain this widget 2022 in_=master - see 'in' option description 2023 ipadx=amount - add internal padding in x direction 2024 ipady=amount - add internal padding in y direction 2025 padx=amount - add padding in x direction 2026 pady=amount - add padding in y direction 2027 row=number - use cell identified with given row (starting with 0) 2028 rowspan=number - this widget will span several rows 2029 sticky=NSEW - if cell is larger on which sides will this 2030 widget stick to the cell boundary 2031 """ 2032 self.tk.call( 2033 ('grid', 'configure', self._w) 2034 + self._options(cnf, kw)) 2035 grid = configure = config = grid_configure 2036 bbox = grid_bbox = Misc.grid_bbox 2037 columnconfigure = grid_columnconfigure = Misc.grid_columnconfigure 2038 def grid_forget(self): 2039 """Unmap this widget.""" 2040 self.tk.call('grid', 'forget', self._w) 2041 forget = grid_forget 2042 def grid_remove(self): 2043 """Unmap this widget but remember the grid options.""" 2044 self.tk.call('grid', 'remove', self._w) 2045 def grid_info(self): 2046 """Return information about the options 2047 for positioning this widget in a grid.""" 2048 d = _splitdict(self.tk, self.tk.call('grid', 'info', self._w)) 2049 if 'in' in d: 2050 d['in'] = self.nametowidget(d['in']) 2051 return d 2052 info = grid_info 2053 location = grid_location = Misc.grid_location 2054 propagate = grid_propagate = Misc.grid_propagate 2055 rowconfigure = grid_rowconfigure = Misc.grid_rowconfigure 2056 size = grid_size = Misc.grid_size 2057 slaves = grid_slaves = Misc.grid_slaves 2058 2059class BaseWidget(Misc): 2060 """Internal class.""" 2061 def _setup(self, master, cnf): 2062 """Internal function. Sets up information about children.""" 2063 if _support_default_root: 2064 global _default_root 2065 if not master: 2066 if not _default_root: 2067 _default_root = Tk() 2068 master = _default_root 2069 self.master = master 2070 self.tk = master.tk 2071 name = None 2072 if 'name' in cnf: 2073 name = cnf['name'] 2074 del cnf['name'] 2075 if not name: 2076 name = repr(id(self)) 2077 self._name = name 2078 if master._w=='.': 2079 self._w = '.' + name 2080 else: 2081 self._w = master._w + '.' + name 2082 self.children = {} 2083 if self._name in self.master.children: 2084 self.master.children[self._name].destroy() 2085 self.master.children[self._name] = self 2086 def __init__(self, master, widgetName, cnf={}, kw={}, extra=()): 2087 """Construct a widget with the parent widget MASTER, a name WIDGETNAME 2088 and appropriate options.""" 2089 if kw: 2090 cnf = _cnfmerge((cnf, kw)) 2091 self.widgetName = widgetName 2092 BaseWidget._setup(self, master, cnf) 2093 if self._tclCommands is None: 2094 self._tclCommands = [] 2095 classes = [] 2096 for k in cnf.keys(): 2097 if type(k) is ClassType: 2098 classes.append((k, cnf[k])) 2099 del cnf[k] 2100 self.tk.call( 2101 (widgetName, self._w) + extra + self._options(cnf)) 2102 for k, v in classes: 2103 k.configure(self, v) 2104 def destroy(self): 2105 """Destroy this and all descendants widgets.""" 2106 for c in self.children.values(): c.destroy() 2107 self.tk.call('destroy', self._w) 2108 if self._name in self.master.children: 2109 del self.master.children[self._name] 2110 Misc.destroy(self) 2111 def _do(self, name, args=()): 2112 # XXX Obsolete -- better use self.tk.call directly! 2113 return self.tk.call((self._w, name) + args) 2114 2115class Widget(BaseWidget, Pack, Place, Grid): 2116 """Internal class. 2117 2118 Base class for a widget which can be positioned with the geometry managers 2119 Pack, Place or Grid.""" 2120 pass 2121 2122class Toplevel(BaseWidget, Wm): 2123 """Toplevel widget, e.g. for dialogs.""" 2124 def __init__(self, master=None, cnf={}, **kw): 2125 """Construct a toplevel widget with the parent MASTER. 2126 2127 Valid resource names: background, bd, bg, borderwidth, class, 2128 colormap, container, cursor, height, highlightbackground, 2129 highlightcolor, highlightthickness, menu, relief, screen, takefocus, 2130 use, visual, width.""" 2131 if kw: 2132 cnf = _cnfmerge((cnf, kw)) 2133 extra = () 2134 for wmkey in ['screen', 'class_', 'class', 'visual', 2135 'colormap']: 2136 if wmkey in cnf: 2137 val = cnf[wmkey] 2138 # TBD: a hack needed because some keys 2139 # are not valid as keyword arguments 2140 if wmkey[-1] == '_': opt = '-'+wmkey[:-1] 2141 else: opt = '-'+wmkey 2142 extra = extra + (opt, val) 2143 del cnf[wmkey] 2144 BaseWidget.__init__(self, master, 'toplevel', cnf, {}, extra) 2145 root = self._root() 2146 self.iconname(root.iconname()) 2147 self.title(root.title()) 2148 self.protocol("WM_DELETE_WINDOW", self.destroy) 2149 2150class Button(Widget): 2151 """Button widget.""" 2152 def __init__(self, master=None, cnf={}, **kw): 2153 """Construct a button widget with the parent MASTER. 2154 2155 STANDARD OPTIONS 2156 2157 activebackground, activeforeground, anchor, 2158 background, bitmap, borderwidth, cursor, 2159 disabledforeground, font, foreground 2160 highlightbackground, highlightcolor, 2161 highlightthickness, image, justify, 2162 padx, pady, relief, repeatdelay, 2163 repeatinterval, takefocus, text, 2164 textvariable, underline, wraplength 2165 2166 WIDGET-SPECIFIC OPTIONS 2167 2168 command, compound, default, height, 2169 overrelief, state, width 2170 """ 2171 Widget.__init__(self, master, 'button', cnf, kw) 2172 2173 def tkButtonEnter(self, *dummy): 2174 self.tk.call('tkButtonEnter', self._w) 2175 2176 def tkButtonLeave(self, *dummy): 2177 self.tk.call('tkButtonLeave', self._w) 2178 2179 def tkButtonDown(self, *dummy): 2180 self.tk.call('tkButtonDown', self._w) 2181 2182 def tkButtonUp(self, *dummy): 2183 self.tk.call('tkButtonUp', self._w) 2184 2185 def tkButtonInvoke(self, *dummy): 2186 self.tk.call('tkButtonInvoke', self._w) 2187 2188 def flash(self): 2189 """Flash the button. 2190 2191 This is accomplished by redisplaying 2192 the button several times, alternating between active and 2193 normal colors. At the end of the flash the button is left 2194 in the same normal/active state as when the command was 2195 invoked. This command is ignored if the button's state is 2196 disabled. 2197 """ 2198 self.tk.call(self._w, 'flash') 2199 2200 def invoke(self): 2201 """Invoke the command associated with the button. 2202 2203 The return value is the return value from the command, 2204 or an empty string if there is no command associated with 2205 the button. This command is ignored if the button's state 2206 is disabled. 2207 """ 2208 return self.tk.call(self._w, 'invoke') 2209 2210# Indices: 2211# XXX I don't like these -- take them away 2212def AtEnd(): 2213 return 'end' 2214def AtInsert(*args): 2215 s = 'insert' 2216 for a in args: 2217 if a: s = s + (' ' + a) 2218 return s 2219def AtSelFirst(): 2220 return 'sel.first' 2221def AtSelLast(): 2222 return 'sel.last' 2223def At(x, y=None): 2224 if y is None: 2225 return '@%r' % (x,) 2226 else: 2227 return '@%r,%r' % (x, y) 2228 2229class Canvas(Widget, XView, YView): 2230 """Canvas widget to display graphical elements like lines or text.""" 2231 def __init__(self, master=None, cnf={}, **kw): 2232 """Construct a canvas widget with the parent MASTER. 2233 2234 Valid resource names: background, bd, bg, borderwidth, closeenough, 2235 confine, cursor, height, highlightbackground, highlightcolor, 2236 highlightthickness, insertbackground, insertborderwidth, 2237 insertofftime, insertontime, insertwidth, offset, relief, 2238 scrollregion, selectbackground, selectborderwidth, selectforeground, 2239 state, takefocus, width, xscrollcommand, xscrollincrement, 2240 yscrollcommand, yscrollincrement.""" 2241 Widget.__init__(self, master, 'canvas', cnf, kw) 2242 def addtag(self, *args): 2243 """Internal function.""" 2244 self.tk.call((self._w, 'addtag') + args) 2245 def addtag_above(self, newtag, tagOrId): 2246 """Add tag NEWTAG to all items above TAGORID.""" 2247 self.addtag(newtag, 'above', tagOrId) 2248 def addtag_all(self, newtag): 2249 """Add tag NEWTAG to all items.""" 2250 self.addtag(newtag, 'all') 2251 def addtag_below(self, newtag, tagOrId): 2252 """Add tag NEWTAG to all items below TAGORID.""" 2253 self.addtag(newtag, 'below', tagOrId) 2254 def addtag_closest(self, newtag, x, y, halo=None, start=None): 2255 """Add tag NEWTAG to item which is closest to pixel at X, Y. 2256 If several match take the top-most. 2257 All items closer than HALO are considered overlapping (all are 2258 closests). If START is specified the next below this tag is taken.""" 2259 self.addtag(newtag, 'closest', x, y, halo, start) 2260 def addtag_enclosed(self, newtag, x1, y1, x2, y2): 2261 """Add tag NEWTAG to all items in the rectangle defined 2262 by X1,Y1,X2,Y2.""" 2263 self.addtag(newtag, 'enclosed', x1, y1, x2, y2) 2264 def addtag_overlapping(self, newtag, x1, y1, x2, y2): 2265 """Add tag NEWTAG to all items which overlap the rectangle 2266 defined by X1,Y1,X2,Y2.""" 2267 self.addtag(newtag, 'overlapping', x1, y1, x2, y2) 2268 def addtag_withtag(self, newtag, tagOrId): 2269 """Add tag NEWTAG to all items with TAGORID.""" 2270 self.addtag(newtag, 'withtag', tagOrId) 2271 def bbox(self, *args): 2272 """Return a tuple of X1,Y1,X2,Y2 coordinates for a rectangle 2273 which encloses all items with tags specified as arguments.""" 2274 return self._getints( 2275 self.tk.call((self._w, 'bbox') + args)) or None 2276 def tag_unbind(self, tagOrId, sequence, funcid=None): 2277 """Unbind for all items with TAGORID for event SEQUENCE the 2278 function identified with FUNCID.""" 2279 self.tk.call(self._w, 'bind', tagOrId, sequence, '') 2280 if funcid: 2281 self.deletecommand(funcid) 2282 def tag_bind(self, tagOrId, sequence=None, func=None, add=None): 2283 """Bind to all items with TAGORID at event SEQUENCE a call to function FUNC. 2284 2285 An additional boolean parameter ADD specifies whether FUNC will be 2286 called additionally to the other bound function or whether it will 2287 replace the previous function. See bind for the return value.""" 2288 return self._bind((self._w, 'bind', tagOrId), 2289 sequence, func, add) 2290 def canvasx(self, screenx, gridspacing=None): 2291 """Return the canvas x coordinate of pixel position SCREENX rounded 2292 to nearest multiple of GRIDSPACING units.""" 2293 return getdouble(self.tk.call( 2294 self._w, 'canvasx', screenx, gridspacing)) 2295 def canvasy(self, screeny, gridspacing=None): 2296 """Return the canvas y coordinate of pixel position SCREENY rounded 2297 to nearest multiple of GRIDSPACING units.""" 2298 return getdouble(self.tk.call( 2299 self._w, 'canvasy', screeny, gridspacing)) 2300 def coords(self, *args): 2301 """Return a list of coordinates for the item given in ARGS.""" 2302 # XXX Should use _flatten on args 2303 return map(getdouble, 2304 self.tk.splitlist( 2305 self.tk.call((self._w, 'coords') + args))) 2306 def _create(self, itemType, args, kw): # Args: (val, val, ..., cnf={}) 2307 """Internal function.""" 2308 args = _flatten(args) 2309 cnf = args[-1] 2310 if type(cnf) in (DictionaryType, TupleType): 2311 args = args[:-1] 2312 else: 2313 cnf = {} 2314 return getint(self.tk.call( 2315 self._w, 'create', itemType, 2316 *(args + self._options(cnf, kw)))) 2317 def create_arc(self, *args, **kw): 2318 """Create arc shaped region with coordinates x1,y1,x2,y2.""" 2319 return self._create('arc', args, kw) 2320 def create_bitmap(self, *args, **kw): 2321 """Create bitmap with coordinates x1,y1.""" 2322 return self._create('bitmap', args, kw) 2323 def create_image(self, *args, **kw): 2324 """Create image item with coordinates x1,y1.""" 2325 return self._create('image', args, kw) 2326 def create_line(self, *args, **kw): 2327 """Create line with coordinates x1,y1,...,xn,yn.""" 2328 return self._create('line', args, kw) 2329 def create_oval(self, *args, **kw): 2330 """Create oval with coordinates x1,y1,x2,y2.""" 2331 return self._create('oval', args, kw) 2332 def create_polygon(self, *args, **kw): 2333 """Create polygon with coordinates x1,y1,...,xn,yn.""" 2334 return self._create('polygon', args, kw) 2335 def create_rectangle(self, *args, **kw): 2336 """Create rectangle with coordinates x1,y1,x2,y2.""" 2337 return self._create('rectangle', args, kw) 2338 def create_text(self, *args, **kw): 2339 """Create text with coordinates x1,y1.""" 2340 return self._create('text', args, kw) 2341 def create_window(self, *args, **kw): 2342 """Create window with coordinates x1,y1,x2,y2.""" 2343 return self._create('window', args, kw) 2344 def dchars(self, *args): 2345 """Delete characters of text items identified by tag or id in ARGS (possibly 2346 several times) from FIRST to LAST character (including).""" 2347 self.tk.call((self._w, 'dchars') + args) 2348 def delete(self, *args): 2349 """Delete items identified by all tag or ids contained in ARGS.""" 2350 self.tk.call((self._w, 'delete') + args) 2351 def dtag(self, *args): 2352 """Delete tag or id given as last arguments in ARGS from items 2353 identified by first argument in ARGS.""" 2354 self.tk.call((self._w, 'dtag') + args) 2355 def find(self, *args): 2356 """Internal function.""" 2357 return self._getints( 2358 self.tk.call((self._w, 'find') + args)) or () 2359 def find_above(self, tagOrId): 2360 """Return items above TAGORID.""" 2361 return self.find('above', tagOrId) 2362 def find_all(self): 2363 """Return all items.""" 2364 return self.find('all') 2365 def find_below(self, tagOrId): 2366 """Return all items below TAGORID.""" 2367 return self.find('below', tagOrId) 2368 def find_closest(self, x, y, halo=None, start=None): 2369 """Return item which is closest to pixel at X, Y. 2370 If several match take the top-most. 2371 All items closer than HALO are considered overlapping (all are 2372 closest). If START is specified the next below this tag is taken.""" 2373 return self.find('closest', x, y, halo, start) 2374 def find_enclosed(self, x1, y1, x2, y2): 2375 """Return all items in rectangle defined 2376 by X1,Y1,X2,Y2.""" 2377 return self.find('enclosed', x1, y1, x2, y2) 2378 def find_overlapping(self, x1, y1, x2, y2): 2379 """Return all items which overlap the rectangle 2380 defined by X1,Y1,X2,Y2.""" 2381 return self.find('overlapping', x1, y1, x2, y2) 2382 def find_withtag(self, tagOrId): 2383 """Return all items with TAGORID.""" 2384 return self.find('withtag', tagOrId) 2385 def focus(self, *args): 2386 """Set focus to the first item specified in ARGS.""" 2387 return self.tk.call((self._w, 'focus') + args) 2388 def gettags(self, *args): 2389 """Return tags associated with the first item specified in ARGS.""" 2390 return self.tk.splitlist( 2391 self.tk.call((self._w, 'gettags') + args)) 2392 def icursor(self, *args): 2393 """Set cursor at position POS in the item identified by TAGORID. 2394 In ARGS TAGORID must be first.""" 2395 self.tk.call((self._w, 'icursor') + args) 2396 def index(self, *args): 2397 """Return position of cursor as integer in item specified in ARGS.""" 2398 return getint(self.tk.call((self._w, 'index') + args)) 2399 def insert(self, *args): 2400 """Insert TEXT in item TAGORID at position POS. ARGS must 2401 be TAGORID POS TEXT.""" 2402 self.tk.call((self._w, 'insert') + args) 2403 def itemcget(self, tagOrId, option): 2404 """Return the resource value for an OPTION for item TAGORID.""" 2405 return self.tk.call( 2406 (self._w, 'itemcget') + (tagOrId, '-'+option)) 2407 def itemconfigure(self, tagOrId, cnf=None, **kw): 2408 """Configure resources of an item TAGORID. 2409 2410 The values for resources are specified as keyword 2411 arguments. To get an overview about 2412 the allowed keyword arguments call the method without arguments. 2413 """ 2414 return self._configure(('itemconfigure', tagOrId), cnf, kw) 2415 itemconfig = itemconfigure 2416 # lower, tkraise/lift hide Misc.lower, Misc.tkraise/lift, 2417 # so the preferred name for them is tag_lower, tag_raise 2418 # (similar to tag_bind, and similar to the Text widget); 2419 # unfortunately can't delete the old ones yet (maybe in 1.6) 2420 def tag_lower(self, *args): 2421 """Lower an item TAGORID given in ARGS 2422 (optional below another item).""" 2423 self.tk.call((self._w, 'lower') + args) 2424 lower = tag_lower 2425 def move(self, *args): 2426 """Move an item TAGORID given in ARGS.""" 2427 self.tk.call((self._w, 'move') + args) 2428 def postscript(self, cnf={}, **kw): 2429 """Print the contents of the canvas to a postscript 2430 file. Valid options: colormap, colormode, file, fontmap, 2431 height, pageanchor, pageheight, pagewidth, pagex, pagey, 2432 rotate, width, x, y.""" 2433 return self.tk.call((self._w, 'postscript') + 2434 self._options(cnf, kw)) 2435 def tag_raise(self, *args): 2436 """Raise an item TAGORID given in ARGS 2437 (optional above another item).""" 2438 self.tk.call((self._w, 'raise') + args) 2439 lift = tkraise = tag_raise 2440 def scale(self, *args): 2441 """Scale item TAGORID with XORIGIN, YORIGIN, XSCALE, YSCALE.""" 2442 self.tk.call((self._w, 'scale') + args) 2443 def scan_mark(self, x, y): 2444 """Remember the current X, Y coordinates.""" 2445 self.tk.call(self._w, 'scan', 'mark', x, y) 2446 def scan_dragto(self, x, y, gain=10): 2447 """Adjust the view of the canvas to GAIN times the 2448 difference between X and Y and the coordinates given in 2449 scan_mark.""" 2450 self.tk.call(self._w, 'scan', 'dragto', x, y, gain) 2451 def select_adjust(self, tagOrId, index): 2452 """Adjust the end of the selection near the cursor of an item TAGORID to index.""" 2453 self.tk.call(self._w, 'select', 'adjust', tagOrId, index) 2454 def select_clear(self): 2455 """Clear the selection if it is in this widget.""" 2456 self.tk.call(self._w, 'select', 'clear') 2457 def select_from(self, tagOrId, index): 2458 """Set the fixed end of a selection in item TAGORID to INDEX.""" 2459 self.tk.call(self._w, 'select', 'from', tagOrId, index) 2460 def select_item(self): 2461 """Return the item which has the selection.""" 2462 return self.tk.call(self._w, 'select', 'item') or None 2463 def select_to(self, tagOrId, index): 2464 """Set the variable end of a selection in item TAGORID to INDEX.""" 2465 self.tk.call(self._w, 'select', 'to', tagOrId, index) 2466 def type(self, tagOrId): 2467 """Return the type of the item TAGORID.""" 2468 return self.tk.call(self._w, 'type', tagOrId) or None 2469 2470class Checkbutton(Widget): 2471 """Checkbutton widget which is either in on- or off-state.""" 2472 def __init__(self, master=None, cnf={}, **kw): 2473 """Construct a checkbutton widget with the parent MASTER. 2474 2475 Valid resource names: activebackground, activeforeground, anchor, 2476 background, bd, bg, bitmap, borderwidth, command, cursor, 2477 disabledforeground, fg, font, foreground, height, 2478 highlightbackground, highlightcolor, highlightthickness, image, 2479 indicatoron, justify, offvalue, onvalue, padx, pady, relief, 2480 selectcolor, selectimage, state, takefocus, text, textvariable, 2481 underline, variable, width, wraplength.""" 2482 Widget.__init__(self, master, 'checkbutton', cnf, kw) 2483 def deselect(self): 2484 """Put the button in off-state.""" 2485 self.tk.call(self._w, 'deselect') 2486 def flash(self): 2487 """Flash the button.""" 2488 self.tk.call(self._w, 'flash') 2489 def invoke(self): 2490 """Toggle the button and invoke a command if given as resource.""" 2491 return self.tk.call(self._w, 'invoke') 2492 def select(self): 2493 """Put the button in on-state.""" 2494 self.tk.call(self._w, 'select') 2495 def toggle(self): 2496 """Toggle the button.""" 2497 self.tk.call(self._w, 'toggle') 2498 2499class Entry(Widget, XView): 2500 """Entry widget which allows displaying simple text.""" 2501 def __init__(self, master=None, cnf={}, **kw): 2502 """Construct an entry widget with the parent MASTER. 2503 2504 Valid resource names: background, bd, bg, borderwidth, cursor, 2505 exportselection, fg, font, foreground, highlightbackground, 2506 highlightcolor, highlightthickness, insertbackground, 2507 insertborderwidth, insertofftime, insertontime, insertwidth, 2508 invalidcommand, invcmd, justify, relief, selectbackground, 2509 selectborderwidth, selectforeground, show, state, takefocus, 2510 textvariable, validate, validatecommand, vcmd, width, 2511 xscrollcommand.""" 2512 Widget.__init__(self, master, 'entry', cnf, kw) 2513 def delete(self, first, last=None): 2514 """Delete text from FIRST to LAST (not included).""" 2515 self.tk.call(self._w, 'delete', first, last) 2516 def get(self): 2517 """Return the text.""" 2518 return self.tk.call(self._w, 'get') 2519 def icursor(self, index): 2520 """Insert cursor at INDEX.""" 2521 self.tk.call(self._w, 'icursor', index) 2522 def index(self, index): 2523 """Return position of cursor.""" 2524 return getint(self.tk.call( 2525 self._w, 'index', index)) 2526 def insert(self, index, string): 2527 """Insert STRING at INDEX.""" 2528 self.tk.call(self._w, 'insert', index, string) 2529 def scan_mark(self, x): 2530 """Remember the current X, Y coordinates.""" 2531 self.tk.call(self._w, 'scan', 'mark', x) 2532 def scan_dragto(self, x): 2533 """Adjust the view of the canvas to 10 times the 2534 difference between X and Y and the coordinates given in 2535 scan_mark.""" 2536 self.tk.call(self._w, 'scan', 'dragto', x) 2537 def selection_adjust(self, index): 2538 """Adjust the end of the selection near the cursor to INDEX.""" 2539 self.tk.call(self._w, 'selection', 'adjust', index) 2540 select_adjust = selection_adjust 2541 def selection_clear(self): 2542 """Clear the selection if it is in this widget.""" 2543 self.tk.call(self._w, 'selection', 'clear') 2544 select_clear = selection_clear 2545 def selection_from(self, index): 2546 """Set the fixed end of a selection to INDEX.""" 2547 self.tk.call(self._w, 'selection', 'from', index) 2548 select_from = selection_from 2549 def selection_present(self): 2550 """Return True if there are characters selected in the entry, False 2551 otherwise.""" 2552 return self.tk.getboolean( 2553 self.tk.call(self._w, 'selection', 'present')) 2554 select_present = selection_present 2555 def selection_range(self, start, end): 2556 """Set the selection from START to END (not included).""" 2557 self.tk.call(self._w, 'selection', 'range', start, end) 2558 select_range = selection_range 2559 def selection_to(self, index): 2560 """Set the variable end of a selection to INDEX.""" 2561 self.tk.call(self._w, 'selection', 'to', index) 2562 select_to = selection_to 2563 2564class Frame(Widget): 2565 """Frame widget which may contain other widgets and can have a 3D border.""" 2566 def __init__(self, master=None, cnf={}, **kw): 2567 """Construct a frame widget with the parent MASTER. 2568 2569 Valid resource names: background, bd, bg, borderwidth, class, 2570 colormap, container, cursor, height, highlightbackground, 2571 highlightcolor, highlightthickness, relief, takefocus, visual, width.""" 2572 cnf = _cnfmerge((cnf, kw)) 2573 extra = () 2574 if 'class_' in cnf: 2575 extra = ('-class', cnf['class_']) 2576 del cnf['class_'] 2577 elif 'class' in cnf: 2578 extra = ('-class', cnf['class']) 2579 del cnf['class'] 2580 Widget.__init__(self, master, 'frame', cnf, {}, extra) 2581 2582class Label(Widget): 2583 """Label widget which can display text and bitmaps.""" 2584 def __init__(self, master=None, cnf={}, **kw): 2585 """Construct a label widget with the parent MASTER. 2586 2587 STANDARD OPTIONS 2588 2589 activebackground, activeforeground, anchor, 2590 background, bitmap, borderwidth, cursor, 2591 disabledforeground, font, foreground, 2592 highlightbackground, highlightcolor, 2593 highlightthickness, image, justify, 2594 padx, pady, relief, takefocus, text, 2595 textvariable, underline, wraplength 2596 2597 WIDGET-SPECIFIC OPTIONS 2598 2599 height, state, width 2600 2601 """ 2602 Widget.__init__(self, master, 'label', cnf, kw) 2603 2604class Listbox(Widget, XView, YView): 2605 """Listbox widget which can display a list of strings.""" 2606 def __init__(self, master=None, cnf={}, **kw): 2607 """Construct a listbox widget with the parent MASTER. 2608 2609 Valid resource names: background, bd, bg, borderwidth, cursor, 2610 exportselection, fg, font, foreground, height, highlightbackground, 2611 highlightcolor, highlightthickness, relief, selectbackground, 2612 selectborderwidth, selectforeground, selectmode, setgrid, takefocus, 2613 width, xscrollcommand, yscrollcommand, listvariable.""" 2614 Widget.__init__(self, master, 'listbox', cnf, kw) 2615 def activate(self, index): 2616 """Activate item identified by INDEX.""" 2617 self.tk.call(self._w, 'activate', index) 2618 def bbox(self, index): 2619 """Return a tuple of X1,Y1,X2,Y2 coordinates for a rectangle 2620 which encloses the item identified by the given index.""" 2621 return self._getints(self.tk.call(self._w, 'bbox', index)) or None 2622 def curselection(self): 2623 """Return the indices of currently selected item.""" 2624 return self._getints(self.tk.call(self._w, 'curselection')) or () 2625 def delete(self, first, last=None): 2626 """Delete items from FIRST to LAST (included).""" 2627 self.tk.call(self._w, 'delete', first, last) 2628 def get(self, first, last=None): 2629 """Get list of items from FIRST to LAST (included).""" 2630 if last is not None: 2631 return self.tk.splitlist(self.tk.call( 2632 self._w, 'get', first, last)) 2633 else: 2634 return self.tk.call(self._w, 'get', first) 2635 def index(self, index): 2636 """Return index of item identified with INDEX.""" 2637 i = self.tk.call(self._w, 'index', index) 2638 if i == 'none': return None 2639 return getint(i) 2640 def insert(self, index, *elements): 2641 """Insert ELEMENTS at INDEX.""" 2642 self.tk.call((self._w, 'insert', index) + elements) 2643 def nearest(self, y): 2644 """Get index of item which is nearest to y coordinate Y.""" 2645 return getint(self.tk.call( 2646 self._w, 'nearest', y)) 2647 def scan_mark(self, x, y): 2648 """Remember the current X, Y coordinates.""" 2649 self.tk.call(self._w, 'scan', 'mark', x, y) 2650 def scan_dragto(self, x, y): 2651 """Adjust the view of the listbox to 10 times the 2652 difference between X and Y and the coordinates given in 2653 scan_mark.""" 2654 self.tk.call(self._w, 'scan', 'dragto', x, y) 2655 def see(self, index): 2656 """Scroll such that INDEX is visible.""" 2657 self.tk.call(self._w, 'see', index) 2658 def selection_anchor(self, index): 2659 """Set the fixed end oft the selection to INDEX.""" 2660 self.tk.call(self._w, 'selection', 'anchor', index) 2661 select_anchor = selection_anchor 2662 def selection_clear(self, first, last=None): 2663 """Clear the selection from FIRST to LAST (included).""" 2664 self.tk.call(self._w, 2665 'selection', 'clear', first, last) 2666 select_clear = selection_clear 2667 def selection_includes(self, index): 2668 """Return 1 if INDEX is part of the selection.""" 2669 return self.tk.getboolean(self.tk.call( 2670 self._w, 'selection', 'includes', index)) 2671 select_includes = selection_includes 2672 def selection_set(self, first, last=None): 2673 """Set the selection from FIRST to LAST (included) without 2674 changing the currently selected elements.""" 2675 self.tk.call(self._w, 'selection', 'set', first, last) 2676 select_set = selection_set 2677 def size(self): 2678 """Return the number of elements in the listbox.""" 2679 return getint(self.tk.call(self._w, 'size')) 2680 def itemcget(self, index, option): 2681 """Return the resource value for an ITEM and an OPTION.""" 2682 return self.tk.call( 2683 (self._w, 'itemcget') + (index, '-'+option)) 2684 def itemconfigure(self, index, cnf=None, **kw): 2685 """Configure resources of an ITEM. 2686 2687 The values for resources are specified as keyword arguments. 2688 To get an overview about the allowed keyword arguments 2689 call the method without arguments. 2690 Valid resource names: background, bg, foreground, fg, 2691 selectbackground, selectforeground.""" 2692 return self._configure(('itemconfigure', index), cnf, kw) 2693 itemconfig = itemconfigure 2694 2695class Menu(Widget): 2696 """Menu widget which allows displaying menu bars, pull-down menus and pop-up menus.""" 2697 def __init__(self, master=None, cnf={}, **kw): 2698 """Construct menu widget with the parent MASTER. 2699 2700 Valid resource names: activebackground, activeborderwidth, 2701 activeforeground, background, bd, bg, borderwidth, cursor, 2702 disabledforeground, fg, font, foreground, postcommand, relief, 2703 selectcolor, takefocus, tearoff, tearoffcommand, title, type.""" 2704 Widget.__init__(self, master, 'menu', cnf, kw) 2705 def tk_bindForTraversal(self): 2706 # obsolete since Tk 4.0 2707 import warnings 2708 warnings.warn('tk_bindForTraversal() does nothing and ' 2709 'will be removed in 3.6', 2710 DeprecationWarning, stacklevel=2) 2711 def tk_mbPost(self): 2712 self.tk.call('tk_mbPost', self._w) 2713 def tk_mbUnpost(self): 2714 self.tk.call('tk_mbUnpost') 2715 def tk_traverseToMenu(self, char): 2716 self.tk.call('tk_traverseToMenu', self._w, char) 2717 def tk_traverseWithinMenu(self, char): 2718 self.tk.call('tk_traverseWithinMenu', self._w, char) 2719 def tk_getMenuButtons(self): 2720 return self.tk.call('tk_getMenuButtons', self._w) 2721 def tk_nextMenu(self, count): 2722 self.tk.call('tk_nextMenu', count) 2723 def tk_nextMenuEntry(self, count): 2724 self.tk.call('tk_nextMenuEntry', count) 2725 def tk_invokeMenu(self): 2726 self.tk.call('tk_invokeMenu', self._w) 2727 def tk_firstMenu(self): 2728 self.tk.call('tk_firstMenu', self._w) 2729 def tk_mbButtonDown(self): 2730 self.tk.call('tk_mbButtonDown', self._w) 2731 def tk_popup(self, x, y, entry=""): 2732 """Post the menu at position X,Y with entry ENTRY.""" 2733 self.tk.call('tk_popup', self._w, x, y, entry) 2734 def activate(self, index): 2735 """Activate entry at INDEX.""" 2736 self.tk.call(self._w, 'activate', index) 2737 def add(self, itemType, cnf={}, **kw): 2738 """Internal function.""" 2739 self.tk.call((self._w, 'add', itemType) + 2740 self._options(cnf, kw)) 2741 def add_cascade(self, cnf={}, **kw): 2742 """Add hierarchical menu item.""" 2743 self.add('cascade', cnf or kw) 2744 def add_checkbutton(self, cnf={}, **kw): 2745 """Add checkbutton menu item.""" 2746 self.add('checkbutton', cnf or kw) 2747 def add_command(self, cnf={}, **kw): 2748 """Add command menu item.""" 2749 self.add('command', cnf or kw) 2750 def add_radiobutton(self, cnf={}, **kw): 2751 """Addd radio menu item.""" 2752 self.add('radiobutton', cnf or kw) 2753 def add_separator(self, cnf={}, **kw): 2754 """Add separator.""" 2755 self.add('separator', cnf or kw) 2756 def insert(self, index, itemType, cnf={}, **kw): 2757 """Internal function.""" 2758 self.tk.call((self._w, 'insert', index, itemType) + 2759 self._options(cnf, kw)) 2760 def insert_cascade(self, index, cnf={}, **kw): 2761 """Add hierarchical menu item at INDEX.""" 2762 self.insert(index, 'cascade', cnf or kw) 2763 def insert_checkbutton(self, index, cnf={}, **kw): 2764 """Add checkbutton menu item at INDEX.""" 2765 self.insert(index, 'checkbutton', cnf or kw) 2766 def insert_command(self, index, cnf={}, **kw): 2767 """Add command menu item at INDEX.""" 2768 self.insert(index, 'command', cnf or kw) 2769 def insert_radiobutton(self, index, cnf={}, **kw): 2770 """Addd radio menu item at INDEX.""" 2771 self.insert(index, 'radiobutton', cnf or kw) 2772 def insert_separator(self, index, cnf={}, **kw): 2773 """Add separator at INDEX.""" 2774 self.insert(index, 'separator', cnf or kw) 2775 def delete(self, index1, index2=None): 2776 """Delete menu items between INDEX1 and INDEX2 (included).""" 2777 if index2 is None: 2778 index2 = index1 2779 2780 num_index1, num_index2 = self.index(index1), self.index(index2) 2781 if (num_index1 is None) or (num_index2 is None): 2782 num_index1, num_index2 = 0, -1 2783 2784 for i in range(num_index1, num_index2 + 1): 2785 if 'command' in self.entryconfig(i): 2786 c = str(self.entrycget(i, 'command')) 2787 if c: 2788 self.deletecommand(c) 2789 self.tk.call(self._w, 'delete', index1, index2) 2790 def entrycget(self, index, option): 2791 """Return the resource value of a menu item for OPTION at INDEX.""" 2792 return self.tk.call(self._w, 'entrycget', index, '-' + option) 2793 def entryconfigure(self, index, cnf=None, **kw): 2794 """Configure a menu item at INDEX.""" 2795 return self._configure(('entryconfigure', index), cnf, kw) 2796 entryconfig = entryconfigure 2797 def index(self, index): 2798 """Return the index of a menu item identified by INDEX.""" 2799 i = self.tk.call(self._w, 'index', index) 2800 if i == 'none': return None 2801 return getint(i) 2802 def invoke(self, index): 2803 """Invoke a menu item identified by INDEX and execute 2804 the associated command.""" 2805 return self.tk.call(self._w, 'invoke', index) 2806 def post(self, x, y): 2807 """Display a menu at position X,Y.""" 2808 self.tk.call(self._w, 'post', x, y) 2809 def type(self, index): 2810 """Return the type of the menu item at INDEX.""" 2811 return self.tk.call(self._w, 'type', index) 2812 def unpost(self): 2813 """Unmap a menu.""" 2814 self.tk.call(self._w, 'unpost') 2815 def yposition(self, index): 2816 """Return the y-position of the topmost pixel of the menu item at INDEX.""" 2817 return getint(self.tk.call( 2818 self._w, 'yposition', index)) 2819 2820class Menubutton(Widget): 2821 """Menubutton widget, obsolete since Tk8.0.""" 2822 def __init__(self, master=None, cnf={}, **kw): 2823 Widget.__init__(self, master, 'menubutton', cnf, kw) 2824 2825class Message(Widget): 2826 """Message widget to display multiline text. Obsolete since Label does it too.""" 2827 def __init__(self, master=None, cnf={}, **kw): 2828 Widget.__init__(self, master, 'message', cnf, kw) 2829 2830class Radiobutton(Widget): 2831 """Radiobutton widget which shows only one of several buttons in on-state.""" 2832 def __init__(self, master=None, cnf={}, **kw): 2833 """Construct a radiobutton widget with the parent MASTER. 2834 2835 Valid resource names: activebackground, activeforeground, anchor, 2836 background, bd, bg, bitmap, borderwidth, command, cursor, 2837 disabledforeground, fg, font, foreground, height, 2838 highlightbackground, highlightcolor, highlightthickness, image, 2839 indicatoron, justify, padx, pady, relief, selectcolor, selectimage, 2840 state, takefocus, text, textvariable, underline, value, variable, 2841 width, wraplength.""" 2842 Widget.__init__(self, master, 'radiobutton', cnf, kw) 2843 def deselect(self): 2844 """Put the button in off-state.""" 2845 2846 self.tk.call(self._w, 'deselect') 2847 def flash(self): 2848 """Flash the button.""" 2849 self.tk.call(self._w, 'flash') 2850 def invoke(self): 2851 """Toggle the button and invoke a command if given as resource.""" 2852 return self.tk.call(self._w, 'invoke') 2853 def select(self): 2854 """Put the button in on-state.""" 2855 self.tk.call(self._w, 'select') 2856 2857class Scale(Widget): 2858 """Scale widget which can display a numerical scale.""" 2859 def __init__(self, master=None, cnf={}, **kw): 2860 """Construct a scale widget with the parent MASTER. 2861 2862 Valid resource names: activebackground, background, bigincrement, bd, 2863 bg, borderwidth, command, cursor, digits, fg, font, foreground, from, 2864 highlightbackground, highlightcolor, highlightthickness, label, 2865 length, orient, relief, repeatdelay, repeatinterval, resolution, 2866 showvalue, sliderlength, sliderrelief, state, takefocus, 2867 tickinterval, to, troughcolor, variable, width.""" 2868 Widget.__init__(self, master, 'scale', cnf, kw) 2869 def get(self): 2870 """Get the current value as integer or float.""" 2871 value = self.tk.call(self._w, 'get') 2872 try: 2873 return getint(value) 2874 except ValueError: 2875 return getdouble(value) 2876 def set(self, value): 2877 """Set the value to VALUE.""" 2878 self.tk.call(self._w, 'set', value) 2879 def coords(self, value=None): 2880 """Return a tuple (X,Y) of the point along the centerline of the 2881 trough that corresponds to VALUE or the current value if None is 2882 given.""" 2883 2884 return self._getints(self.tk.call(self._w, 'coords', value)) 2885 def identify(self, x, y): 2886 """Return where the point X,Y lies. Valid return values are "slider", 2887 "though1" and "though2".""" 2888 return self.tk.call(self._w, 'identify', x, y) 2889 2890class Scrollbar(Widget): 2891 """Scrollbar widget which displays a slider at a certain position.""" 2892 def __init__(self, master=None, cnf={}, **kw): 2893 """Construct a scrollbar widget with the parent MASTER. 2894 2895 Valid resource names: activebackground, activerelief, 2896 background, bd, bg, borderwidth, command, cursor, 2897 elementborderwidth, highlightbackground, 2898 highlightcolor, highlightthickness, jump, orient, 2899 relief, repeatdelay, repeatinterval, takefocus, 2900 troughcolor, width.""" 2901 Widget.__init__(self, master, 'scrollbar', cnf, kw) 2902 def activate(self, index): 2903 """Display the element at INDEX with activebackground and activerelief. 2904 INDEX can be "arrow1","slider" or "arrow2".""" 2905 self.tk.call(self._w, 'activate', index) 2906 def delta(self, deltax, deltay): 2907 """Return the fractional change of the scrollbar setting if it 2908 would be moved by DELTAX or DELTAY pixels.""" 2909 return getdouble( 2910 self.tk.call(self._w, 'delta', deltax, deltay)) 2911 def fraction(self, x, y): 2912 """Return the fractional value which corresponds to a slider 2913 position of X,Y.""" 2914 return getdouble(self.tk.call(self._w, 'fraction', x, y)) 2915 def identify(self, x, y): 2916 """Return the element under position X,Y as one of 2917 "arrow1","slider","arrow2" or "".""" 2918 return self.tk.call(self._w, 'identify', x, y) 2919 def get(self): 2920 """Return the current fractional values (upper and lower end) 2921 of the slider position.""" 2922 return self._getdoubles(self.tk.call(self._w, 'get')) 2923 def set(self, *args): 2924 """Set the fractional values of the slider position (upper and 2925 lower ends as value between 0 and 1).""" 2926 self.tk.call((self._w, 'set') + args) 2927 2928 2929 2930class Text(Widget, XView, YView): 2931 """Text widget which can display text in various forms.""" 2932 def __init__(self, master=None, cnf={}, **kw): 2933 """Construct a text widget with the parent MASTER. 2934 2935 STANDARD OPTIONS 2936 2937 background, borderwidth, cursor, 2938 exportselection, font, foreground, 2939 highlightbackground, highlightcolor, 2940 highlightthickness, insertbackground, 2941 insertborderwidth, insertofftime, 2942 insertontime, insertwidth, padx, pady, 2943 relief, selectbackground, 2944 selectborderwidth, selectforeground, 2945 setgrid, takefocus, 2946 xscrollcommand, yscrollcommand, 2947 2948 WIDGET-SPECIFIC OPTIONS 2949 2950 autoseparators, height, maxundo, 2951 spacing1, spacing2, spacing3, 2952 state, tabs, undo, width, wrap, 2953 2954 """ 2955 Widget.__init__(self, master, 'text', cnf, kw) 2956 def bbox(self, *args): 2957 """Return a tuple of (x,y,width,height) which gives the bounding 2958 box of the visible part of the character at the index in ARGS.""" 2959 return self._getints( 2960 self.tk.call((self._w, 'bbox') + args)) or None 2961 def tk_textSelectTo(self, index): 2962 self.tk.call('tk_textSelectTo', self._w, index) 2963 def tk_textBackspace(self): 2964 self.tk.call('tk_textBackspace', self._w) 2965 def tk_textIndexCloser(self, a, b, c): 2966 self.tk.call('tk_textIndexCloser', self._w, a, b, c) 2967 def tk_textResetAnchor(self, index): 2968 self.tk.call('tk_textResetAnchor', self._w, index) 2969 def compare(self, index1, op, index2): 2970 """Return whether between index INDEX1 and index INDEX2 the 2971 relation OP is satisfied. OP is one of <, <=, ==, >=, >, or !=.""" 2972 return self.tk.getboolean(self.tk.call( 2973 self._w, 'compare', index1, op, index2)) 2974 def debug(self, boolean=None): 2975 """Turn on the internal consistency checks of the B-Tree inside the text 2976 widget according to BOOLEAN.""" 2977 if boolean is None: 2978 return self.tk.getboolean(self.tk.call(self._w, 'debug')) 2979 self.tk.call(self._w, 'debug', boolean) 2980 def delete(self, index1, index2=None): 2981 """Delete the characters between INDEX1 and INDEX2 (not included).""" 2982 self.tk.call(self._w, 'delete', index1, index2) 2983 def dlineinfo(self, index): 2984 """Return tuple (x,y,width,height,baseline) giving the bounding box 2985 and baseline position of the visible part of the line containing 2986 the character at INDEX.""" 2987 return self._getints(self.tk.call(self._w, 'dlineinfo', index)) 2988 def dump(self, index1, index2=None, command=None, **kw): 2989 """Return the contents of the widget between index1 and index2. 2990 2991 The type of contents returned in filtered based on the keyword 2992 parameters; if 'all', 'image', 'mark', 'tag', 'text', or 'window' are 2993 given and true, then the corresponding items are returned. The result 2994 is a list of triples of the form (key, value, index). If none of the 2995 keywords are true then 'all' is used by default. 2996 2997 If the 'command' argument is given, it is called once for each element 2998 of the list of triples, with the values of each triple serving as the 2999 arguments to the function. In this case the list is not returned.""" 3000 args = [] 3001 func_name = None 3002 result = None 3003 if not command: 3004 # Never call the dump command without the -command flag, since the 3005 # output could involve Tcl quoting and would be a pain to parse 3006 # right. Instead just set the command to build a list of triples 3007 # as if we had done the parsing. 3008 result = [] 3009 def append_triple(key, value, index, result=result): 3010 result.append((key, value, index)) 3011 command = append_triple 3012 try: 3013 if not isinstance(command, str): 3014 func_name = command = self._register(command) 3015 args += ["-command", command] 3016 for key in kw: 3017 if kw[key]: args.append("-" + key) 3018 args.append(index1) 3019 if index2: 3020 args.append(index2) 3021 self.tk.call(self._w, "dump", *args) 3022 return result 3023 finally: 3024 if func_name: 3025 self.deletecommand(func_name) 3026 3027 ## new in tk8.4 3028 def edit(self, *args): 3029 """Internal method 3030 3031 This method controls the undo mechanism and 3032 the modified flag. The exact behavior of the 3033 command depends on the option argument that 3034 follows the edit argument. The following forms 3035 of the command are currently supported: 3036 3037 edit_modified, edit_redo, edit_reset, edit_separator 3038 and edit_undo 3039 3040 """ 3041 return self.tk.call(self._w, 'edit', *args) 3042 3043 def edit_modified(self, arg=None): 3044 """Get or Set the modified flag 3045 3046 If arg is not specified, returns the modified 3047 flag of the widget. The insert, delete, edit undo and 3048 edit redo commands or the user can set or clear the 3049 modified flag. If boolean is specified, sets the 3050 modified flag of the widget to arg. 3051 """ 3052 return self.edit("modified", arg) 3053 3054 def edit_redo(self): 3055 """Redo the last undone edit 3056 3057 When the undo option is true, reapplies the last 3058 undone edits provided no other edits were done since 3059 then. Generates an error when the redo stack is empty. 3060 Does nothing when the undo option is false. 3061 """ 3062 return self.edit("redo") 3063 3064 def edit_reset(self): 3065 """Clears the undo and redo stacks 3066 """ 3067 return self.edit("reset") 3068 3069 def edit_separator(self): 3070 """Inserts a separator (boundary) on the undo stack. 3071 3072 Does nothing when the undo option is false 3073 """ 3074 return self.edit("separator") 3075 3076 def edit_undo(self): 3077 """Undoes the last edit action 3078 3079 If the undo option is true. An edit action is defined 3080 as all the insert and delete commands that are recorded 3081 on the undo stack in between two separators. Generates 3082 an error when the undo stack is empty. Does nothing 3083 when the undo option is false 3084 """ 3085 return self.edit("undo") 3086 3087 def get(self, index1, index2=None): 3088 """Return the text from INDEX1 to INDEX2 (not included).""" 3089 return self.tk.call(self._w, 'get', index1, index2) 3090 # (Image commands are new in 8.0) 3091 def image_cget(self, index, option): 3092 """Return the value of OPTION of an embedded image at INDEX.""" 3093 if option[:1] != "-": 3094 option = "-" + option 3095 if option[-1:] == "_": 3096 option = option[:-1] 3097 return self.tk.call(self._w, "image", "cget", index, option) 3098 def image_configure(self, index, cnf=None, **kw): 3099 """Configure an embedded image at INDEX.""" 3100 return self._configure(('image', 'configure', index), cnf, kw) 3101 def image_create(self, index, cnf={}, **kw): 3102 """Create an embedded image at INDEX.""" 3103 return self.tk.call( 3104 self._w, "image", "create", index, 3105 *self._options(cnf, kw)) 3106 def image_names(self): 3107 """Return all names of embedded images in this widget.""" 3108 return self.tk.call(self._w, "image", "names") 3109 def index(self, index): 3110 """Return the index in the form line.char for INDEX.""" 3111 return str(self.tk.call(self._w, 'index', index)) 3112 def insert(self, index, chars, *args): 3113 """Insert CHARS before the characters at INDEX. An additional 3114 tag can be given in ARGS. Additional CHARS and tags can follow in ARGS.""" 3115 self.tk.call((self._w, 'insert', index, chars) + args) 3116 def mark_gravity(self, markName, direction=None): 3117 """Change the gravity of a mark MARKNAME to DIRECTION (LEFT or RIGHT). 3118 Return the current value if None is given for DIRECTION.""" 3119 return self.tk.call( 3120 (self._w, 'mark', 'gravity', markName, direction)) 3121 def mark_names(self): 3122 """Return all mark names.""" 3123 return self.tk.splitlist(self.tk.call( 3124 self._w, 'mark', 'names')) 3125 def mark_set(self, markName, index): 3126 """Set mark MARKNAME before the character at INDEX.""" 3127 self.tk.call(self._w, 'mark', 'set', markName, index) 3128 def mark_unset(self, *markNames): 3129 """Delete all marks in MARKNAMES.""" 3130 self.tk.call((self._w, 'mark', 'unset') + markNames) 3131 def mark_next(self, index): 3132 """Return the name of the next mark after INDEX.""" 3133 return self.tk.call(self._w, 'mark', 'next', index) or None 3134 def mark_previous(self, index): 3135 """Return the name of the previous mark before INDEX.""" 3136 return self.tk.call(self._w, 'mark', 'previous', index) or None 3137 def scan_mark(self, x, y): 3138 """Remember the current X, Y coordinates.""" 3139 self.tk.call(self._w, 'scan', 'mark', x, y) 3140 def scan_dragto(self, x, y): 3141 """Adjust the view of the text to 10 times the 3142 difference between X and Y and the coordinates given in 3143 scan_mark.""" 3144 self.tk.call(self._w, 'scan', 'dragto', x, y) 3145 def search(self, pattern, index, stopindex=None, 3146 forwards=None, backwards=None, exact=None, 3147 regexp=None, nocase=None, count=None, elide=None): 3148 """Search PATTERN beginning from INDEX until STOPINDEX. 3149 Return the index of the first character of a match or an 3150 empty string.""" 3151 args = [self._w, 'search'] 3152 if forwards: args.append('-forwards') 3153 if backwards: args.append('-backwards') 3154 if exact: args.append('-exact') 3155 if regexp: args.append('-regexp') 3156 if nocase: args.append('-nocase') 3157 if elide: args.append('-elide') 3158 if count: args.append('-count'); args.append(count) 3159 if pattern and pattern[0] == '-': args.append('--') 3160 args.append(pattern) 3161 args.append(index) 3162 if stopindex: args.append(stopindex) 3163 return str(self.tk.call(tuple(args))) 3164 def see(self, index): 3165 """Scroll such that the character at INDEX is visible.""" 3166 self.tk.call(self._w, 'see', index) 3167 def tag_add(self, tagName, index1, *args): 3168 """Add tag TAGNAME to all characters between INDEX1 and index2 in ARGS. 3169 Additional pairs of indices may follow in ARGS.""" 3170 self.tk.call( 3171 (self._w, 'tag', 'add', tagName, index1) + args) 3172 def tag_unbind(self, tagName, sequence, funcid=None): 3173 """Unbind for all characters with TAGNAME for event SEQUENCE the 3174 function identified with FUNCID.""" 3175 self.tk.call(self._w, 'tag', 'bind', tagName, sequence, '') 3176 if funcid: 3177 self.deletecommand(funcid) 3178 def tag_bind(self, tagName, sequence, func, add=None): 3179 """Bind to all characters with TAGNAME at event SEQUENCE a call to function FUNC. 3180 3181 An additional boolean parameter ADD specifies whether FUNC will be 3182 called additionally to the other bound function or whether it will 3183 replace the previous function. See bind for the return value.""" 3184 return self._bind((self._w, 'tag', 'bind', tagName), 3185 sequence, func, add) 3186 def tag_cget(self, tagName, option): 3187 """Return the value of OPTION for tag TAGNAME.""" 3188 if option[:1] != '-': 3189 option = '-' + option 3190 if option[-1:] == '_': 3191 option = option[:-1] 3192 return self.tk.call(self._w, 'tag', 'cget', tagName, option) 3193 def tag_configure(self, tagName, cnf=None, **kw): 3194 """Configure a tag TAGNAME.""" 3195 return self._configure(('tag', 'configure', tagName), cnf, kw) 3196 tag_config = tag_configure 3197 def tag_delete(self, *tagNames): 3198 """Delete all tags in TAGNAMES.""" 3199 self.tk.call((self._w, 'tag', 'delete') + tagNames) 3200 def tag_lower(self, tagName, belowThis=None): 3201 """Change the priority of tag TAGNAME such that it is lower 3202 than the priority of BELOWTHIS.""" 3203 self.tk.call(self._w, 'tag', 'lower', tagName, belowThis) 3204 def tag_names(self, index=None): 3205 """Return a list of all tag names.""" 3206 return self.tk.splitlist( 3207 self.tk.call(self._w, 'tag', 'names', index)) 3208 def tag_nextrange(self, tagName, index1, index2=None): 3209 """Return a list of start and end index for the first sequence of 3210 characters between INDEX1 and INDEX2 which all have tag TAGNAME. 3211 The text is searched forward from INDEX1.""" 3212 return self.tk.splitlist(self.tk.call( 3213 self._w, 'tag', 'nextrange', tagName, index1, index2)) 3214 def tag_prevrange(self, tagName, index1, index2=None): 3215 """Return a list of start and end index for the first sequence of 3216 characters between INDEX1 and INDEX2 which all have tag TAGNAME. 3217 The text is searched backwards from INDEX1.""" 3218 return self.tk.splitlist(self.tk.call( 3219 self._w, 'tag', 'prevrange', tagName, index1, index2)) 3220 def tag_raise(self, tagName, aboveThis=None): 3221 """Change the priority of tag TAGNAME such that it is higher 3222 than the priority of ABOVETHIS.""" 3223 self.tk.call( 3224 self._w, 'tag', 'raise', tagName, aboveThis) 3225 def tag_ranges(self, tagName): 3226 """Return a list of ranges of text which have tag TAGNAME.""" 3227 return self.tk.splitlist(self.tk.call( 3228 self._w, 'tag', 'ranges', tagName)) 3229 def tag_remove(self, tagName, index1, index2=None): 3230 """Remove tag TAGNAME from all characters between INDEX1 and INDEX2.""" 3231 self.tk.call( 3232 self._w, 'tag', 'remove', tagName, index1, index2) 3233 def window_cget(self, index, option): 3234 """Return the value of OPTION of an embedded window at INDEX.""" 3235 if option[:1] != '-': 3236 option = '-' + option 3237 if option[-1:] == '_': 3238 option = option[:-1] 3239 return self.tk.call(self._w, 'window', 'cget', index, option) 3240 def window_configure(self, index, cnf=None, **kw): 3241 """Configure an embedded window at INDEX.""" 3242 return self._configure(('window', 'configure', index), cnf, kw) 3243 window_config = window_configure 3244 def window_create(self, index, cnf={}, **kw): 3245 """Create a window at INDEX.""" 3246 self.tk.call( 3247 (self._w, 'window', 'create', index) 3248 + self._options(cnf, kw)) 3249 def window_names(self): 3250 """Return all names of embedded windows in this widget.""" 3251 return self.tk.splitlist( 3252 self.tk.call(self._w, 'window', 'names')) 3253 def yview_pickplace(self, *what): 3254 """Obsolete function, use see.""" 3255 self.tk.call((self._w, 'yview', '-pickplace') + what) 3256 3257 3258class _setit: 3259 """Internal class. It wraps the command in the widget OptionMenu.""" 3260 def __init__(self, var, value, callback=None): 3261 self.__value = value 3262 self.__var = var 3263 self.__callback = callback 3264 def __call__(self, *args): 3265 self.__var.set(self.__value) 3266 if self.__callback: 3267 self.__callback(self.__value, *args) 3268 3269class OptionMenu(Menubutton): 3270 """OptionMenu which allows the user to select a value from a menu.""" 3271 def __init__(self, master, variable, value, *values, **kwargs): 3272 """Construct an optionmenu widget with the parent MASTER, with 3273 the resource textvariable set to VARIABLE, the initially selected 3274 value VALUE, the other menu values VALUES and an additional 3275 keyword argument command.""" 3276 kw = {"borderwidth": 2, "textvariable": variable, 3277 "indicatoron": 1, "relief": RAISED, "anchor": "c", 3278 "highlightthickness": 2} 3279 Widget.__init__(self, master, "menubutton", kw) 3280 self.widgetName = 'tk_optionMenu' 3281 menu = self.__menu = Menu(self, name="menu", tearoff=0) 3282 self.menuname = menu._w 3283 # 'command' is the only supported keyword 3284 callback = kwargs.get('command') 3285 if 'command' in kwargs: 3286 del kwargs['command'] 3287 if kwargs: 3288 raise TclError, 'unknown option -'+kwargs.keys()[0] 3289 menu.add_command(label=value, 3290 command=_setit(variable, value, callback)) 3291 for v in values: 3292 menu.add_command(label=v, 3293 command=_setit(variable, v, callback)) 3294 self["menu"] = menu 3295 3296 def __getitem__(self, name): 3297 if name == 'menu': 3298 return self.__menu 3299 return Widget.__getitem__(self, name) 3300 3301 def destroy(self): 3302 """Destroy this widget and the associated menu.""" 3303 Menubutton.destroy(self) 3304 self.__menu = None 3305 3306class Image: 3307 """Base class for images.""" 3308 _last_id = 0 3309 def __init__(self, imgtype, name=None, cnf={}, master=None, **kw): 3310 self.name = None 3311 if not master: 3312 master = _default_root 3313 if not master: 3314 raise RuntimeError, 'Too early to create image' 3315 self.tk = getattr(master, 'tk', master) 3316 if not name: 3317 Image._last_id += 1 3318 name = "pyimage%r" % (Image._last_id,) # tk itself would use image<x> 3319 # The following is needed for systems where id(x) 3320 # can return a negative number, such as Linux/m68k: 3321 if name[0] == '-': name = '_' + name[1:] 3322 if kw and cnf: cnf = _cnfmerge((cnf, kw)) 3323 elif kw: cnf = kw 3324 options = () 3325 for k, v in cnf.items(): 3326 if hasattr(v, '__call__'): 3327 v = self._register(v) 3328 elif k in ('data', 'maskdata'): 3329 v = self.tk._createbytearray(v) 3330 options = options + ('-'+k, v) 3331 self.tk.call(('image', 'create', imgtype, name,) + options) 3332 self.name = name 3333 def __str__(self): return self.name 3334 def __del__(self): 3335 if self.name: 3336 try: 3337 self.tk.call('image', 'delete', self.name) 3338 except TclError: 3339 # May happen if the root was destroyed 3340 pass 3341 def __setitem__(self, key, value): 3342 self.tk.call(self.name, 'configure', '-'+key, value) 3343 def __getitem__(self, key): 3344 return self.tk.call(self.name, 'configure', '-'+key) 3345 def configure(self, **kw): 3346 """Configure the image.""" 3347 res = () 3348 for k, v in _cnfmerge(kw).items(): 3349 if v is not None: 3350 if k[-1] == '_': k = k[:-1] 3351 if hasattr(v, '__call__'): 3352 v = self._register(v) 3353 elif k in ('data', 'maskdata'): 3354 v = self.tk._createbytearray(v) 3355 res = res + ('-'+k, v) 3356 self.tk.call((self.name, 'config') + res) 3357 config = configure 3358 def height(self): 3359 """Return the height of the image.""" 3360 return getint( 3361 self.tk.call('image', 'height', self.name)) 3362 def type(self): 3363 """Return the type of the image, e.g. "photo" or "bitmap".""" 3364 return self.tk.call('image', 'type', self.name) 3365 def width(self): 3366 """Return the width of the image.""" 3367 return getint( 3368 self.tk.call('image', 'width', self.name)) 3369 3370class PhotoImage(Image): 3371 """Widget which can display images in PGM, PPM, GIF, PNG format.""" 3372 def __init__(self, name=None, cnf={}, master=None, **kw): 3373 """Create an image with NAME. 3374 3375 Valid resource names: data, format, file, gamma, height, palette, 3376 width.""" 3377 Image.__init__(self, 'photo', name, cnf, master, **kw) 3378 def blank(self): 3379 """Display a transparent image.""" 3380 self.tk.call(self.name, 'blank') 3381 def cget(self, option): 3382 """Return the value of OPTION.""" 3383 return self.tk.call(self.name, 'cget', '-' + option) 3384 # XXX config 3385 def __getitem__(self, key): 3386 return self.tk.call(self.name, 'cget', '-' + key) 3387 # XXX copy -from, -to, ...? 3388 def copy(self): 3389 """Return a new PhotoImage with the same image as this widget.""" 3390 destImage = PhotoImage(master=self.tk) 3391 self.tk.call(destImage, 'copy', self.name) 3392 return destImage 3393 def zoom(self, x, y=''): 3394 """Return a new PhotoImage with the same image as this widget 3395 but zoom it with a factor of x in the X direction and y in the Y 3396 direction. If y is not given, the default value is the same as x. 3397 """ 3398 destImage = PhotoImage(master=self.tk) 3399 if y=='': y=x 3400 self.tk.call(destImage, 'copy', self.name, '-zoom',x,y) 3401 return destImage 3402 def subsample(self, x, y=''): 3403 """Return a new PhotoImage based on the same image as this widget 3404 but use only every Xth or Yth pixel. If y is not given, the 3405 default value is the same as x. 3406 """ 3407 destImage = PhotoImage(master=self.tk) 3408 if y=='': y=x 3409 self.tk.call(destImage, 'copy', self.name, '-subsample',x,y) 3410 return destImage 3411 def get(self, x, y): 3412 """Return the color (red, green, blue) of the pixel at X,Y.""" 3413 return self.tk.call(self.name, 'get', x, y) 3414 def put(self, data, to=None): 3415 """Put row formatted colors to image starting from 3416 position TO, e.g. image.put("{red green} {blue yellow}", to=(4,6))""" 3417 args = (self.name, 'put', data) 3418 if to: 3419 if to[0] == '-to': 3420 to = to[1:] 3421 args = args + ('-to',) + tuple(to) 3422 self.tk.call(args) 3423 # XXX read 3424 def write(self, filename, format=None, from_coords=None): 3425 """Write image to file FILENAME in FORMAT starting from 3426 position FROM_COORDS.""" 3427 args = (self.name, 'write', filename) 3428 if format: 3429 args = args + ('-format', format) 3430 if from_coords: 3431 args = args + ('-from',) + tuple(from_coords) 3432 self.tk.call(args) 3433 3434class BitmapImage(Image): 3435 """Widget which can display images in XBM format.""" 3436 def __init__(self, name=None, cnf={}, master=None, **kw): 3437 """Create a bitmap with NAME. 3438 3439 Valid resource names: background, data, file, foreground, maskdata, maskfile.""" 3440 Image.__init__(self, 'bitmap', name, cnf, master, **kw) 3441 3442def image_names(): 3443 return _default_root.tk.splitlist(_default_root.tk.call('image', 'names')) 3444 3445def image_types(): 3446 return _default_root.tk.splitlist(_default_root.tk.call('image', 'types')) 3447 3448 3449class Spinbox(Widget, XView): 3450 """spinbox widget.""" 3451 def __init__(self, master=None, cnf={}, **kw): 3452 """Construct a spinbox widget with the parent MASTER. 3453 3454 STANDARD OPTIONS 3455 3456 activebackground, background, borderwidth, 3457 cursor, exportselection, font, foreground, 3458 highlightbackground, highlightcolor, 3459 highlightthickness, insertbackground, 3460 insertborderwidth, insertofftime, 3461 insertontime, insertwidth, justify, relief, 3462 repeatdelay, repeatinterval, 3463 selectbackground, selectborderwidth 3464 selectforeground, takefocus, textvariable 3465 xscrollcommand. 3466 3467 WIDGET-SPECIFIC OPTIONS 3468 3469 buttonbackground, buttoncursor, 3470 buttondownrelief, buttonuprelief, 3471 command, disabledbackground, 3472 disabledforeground, format, from, 3473 invalidcommand, increment, 3474 readonlybackground, state, to, 3475 validate, validatecommand values, 3476 width, wrap, 3477 """ 3478 Widget.__init__(self, master, 'spinbox', cnf, kw) 3479 3480 def bbox(self, index): 3481 """Return a tuple of X1,Y1,X2,Y2 coordinates for a 3482 rectangle which encloses the character given by index. 3483 3484 The first two elements of the list give the x and y 3485 coordinates of the upper-left corner of the screen 3486 area covered by the character (in pixels relative 3487 to the widget) and the last two elements give the 3488 width and height of the character, in pixels. The 3489 bounding box may refer to a region outside the 3490 visible area of the window. 3491 """ 3492 return self._getints(self.tk.call(self._w, 'bbox', index)) or None 3493 3494 def delete(self, first, last=None): 3495 """Delete one or more elements of the spinbox. 3496 3497 First is the index of the first character to delete, 3498 and last is the index of the character just after 3499 the last one to delete. If last isn't specified it 3500 defaults to first+1, i.e. a single character is 3501 deleted. This command returns an empty string. 3502 """ 3503 return self.tk.call(self._w, 'delete', first, last) 3504 3505 def get(self): 3506 """Returns the spinbox's string""" 3507 return self.tk.call(self._w, 'get') 3508 3509 def icursor(self, index): 3510 """Alter the position of the insertion cursor. 3511 3512 The insertion cursor will be displayed just before 3513 the character given by index. Returns an empty string 3514 """ 3515 return self.tk.call(self._w, 'icursor', index) 3516 3517 def identify(self, x, y): 3518 """Returns the name of the widget at position x, y 3519 3520 Return value is one of: none, buttondown, buttonup, entry 3521 """ 3522 return self.tk.call(self._w, 'identify', x, y) 3523 3524 def index(self, index): 3525 """Returns the numerical index corresponding to index 3526 """ 3527 return self.tk.call(self._w, 'index', index) 3528 3529 def insert(self, index, s): 3530 """Insert string s at index 3531 3532 Returns an empty string. 3533 """ 3534 return self.tk.call(self._w, 'insert', index, s) 3535 3536 def invoke(self, element): 3537 """Causes the specified element to be invoked 3538 3539 The element could be buttondown or buttonup 3540 triggering the action associated with it. 3541 """ 3542 return self.tk.call(self._w, 'invoke', element) 3543 3544 def scan(self, *args): 3545 """Internal function.""" 3546 return self._getints( 3547 self.tk.call((self._w, 'scan') + args)) or () 3548 3549 def scan_mark(self, x): 3550 """Records x and the current view in the spinbox window; 3551 3552 used in conjunction with later scan dragto commands. 3553 Typically this command is associated with a mouse button 3554 press in the widget. It returns an empty string. 3555 """ 3556 return self.scan("mark", x) 3557 3558 def scan_dragto(self, x): 3559 """Compute the difference between the given x argument 3560 and the x argument to the last scan mark command 3561 3562 It then adjusts the view left or right by 10 times the 3563 difference in x-coordinates. This command is typically 3564 associated with mouse motion events in the widget, to 3565 produce the effect of dragging the spinbox at high speed 3566 through the window. The return value is an empty string. 3567 """ 3568 return self.scan("dragto", x) 3569 3570 def selection(self, *args): 3571 """Internal function.""" 3572 return self._getints( 3573 self.tk.call((self._w, 'selection') + args)) or () 3574 3575 def selection_adjust(self, index): 3576 """Locate the end of the selection nearest to the character 3577 given by index, 3578 3579 Then adjust that end of the selection to be at index 3580 (i.e including but not going beyond index). The other 3581 end of the selection is made the anchor point for future 3582 select to commands. If the selection isn't currently in 3583 the spinbox, then a new selection is created to include 3584 the characters between index and the most recent selection 3585 anchor point, inclusive. Returns an empty string. 3586 """ 3587 return self.selection("adjust", index) 3588 3589 def selection_clear(self): 3590 """Clear the selection 3591 3592 If the selection isn't in this widget then the 3593 command has no effect. Returns an empty string. 3594 """ 3595 return self.selection("clear") 3596 3597 def selection_element(self, element=None): 3598 """Sets or gets the currently selected element. 3599 3600 If a spinbutton element is specified, it will be 3601 displayed depressed 3602 """ 3603 return self.selection("element", element) 3604 3605########################################################################### 3606 3607class LabelFrame(Widget): 3608 """labelframe widget.""" 3609 def __init__(self, master=None, cnf={}, **kw): 3610 """Construct a labelframe widget with the parent MASTER. 3611 3612 STANDARD OPTIONS 3613 3614 borderwidth, cursor, font, foreground, 3615 highlightbackground, highlightcolor, 3616 highlightthickness, padx, pady, relief, 3617 takefocus, text 3618 3619 WIDGET-SPECIFIC OPTIONS 3620 3621 background, class, colormap, container, 3622 height, labelanchor, labelwidget, 3623 visual, width 3624 """ 3625 Widget.__init__(self, master, 'labelframe', cnf, kw) 3626 3627######################################################################## 3628 3629class PanedWindow(Widget): 3630 """panedwindow widget.""" 3631 def __init__(self, master=None, cnf={}, **kw): 3632 """Construct a panedwindow widget with the parent MASTER. 3633 3634 STANDARD OPTIONS 3635 3636 background, borderwidth, cursor, height, 3637 orient, relief, width 3638 3639 WIDGET-SPECIFIC OPTIONS 3640 3641 handlepad, handlesize, opaqueresize, 3642 sashcursor, sashpad, sashrelief, 3643 sashwidth, showhandle, 3644 """ 3645 Widget.__init__(self, master, 'panedwindow', cnf, kw) 3646 3647 def add(self, child, **kw): 3648 """Add a child widget to the panedwindow in a new pane. 3649 3650 The child argument is the name of the child widget 3651 followed by pairs of arguments that specify how to 3652 manage the windows. The possible options and values 3653 are the ones accepted by the paneconfigure method. 3654 """ 3655 self.tk.call((self._w, 'add', child) + self._options(kw)) 3656 3657 def remove(self, child): 3658 """Remove the pane containing child from the panedwindow 3659 3660 All geometry management options for child will be forgotten. 3661 """ 3662 self.tk.call(self._w, 'forget', child) 3663 forget=remove 3664 3665 def identify(self, x, y): 3666 """Identify the panedwindow component at point x, y 3667 3668 If the point is over a sash or a sash handle, the result 3669 is a two element list containing the index of the sash or 3670 handle, and a word indicating whether it is over a sash 3671 or a handle, such as {0 sash} or {2 handle}. If the point 3672 is over any other part of the panedwindow, the result is 3673 an empty list. 3674 """ 3675 return self.tk.call(self._w, 'identify', x, y) 3676 3677 def proxy(self, *args): 3678 """Internal function.""" 3679 return self._getints( 3680 self.tk.call((self._w, 'proxy') + args)) or () 3681 3682 def proxy_coord(self): 3683 """Return the x and y pair of the most recent proxy location 3684 """ 3685 return self.proxy("coord") 3686 3687 def proxy_forget(self): 3688 """Remove the proxy from the display. 3689 """ 3690 return self.proxy("forget") 3691 3692 def proxy_place(self, x, y): 3693 """Place the proxy at the given x and y coordinates. 3694 """ 3695 return self.proxy("place", x, y) 3696 3697 def sash(self, *args): 3698 """Internal function.""" 3699 return self._getints( 3700 self.tk.call((self._w, 'sash') + args)) or () 3701 3702 def sash_coord(self, index): 3703 """Return the current x and y pair for the sash given by index. 3704 3705 Index must be an integer between 0 and 1 less than the 3706 number of panes in the panedwindow. The coordinates given are 3707 those of the top left corner of the region containing the sash. 3708 pathName sash dragto index x y This command computes the 3709 difference between the given coordinates and the coordinates 3710 given to the last sash coord command for the given sash. It then 3711 moves that sash the computed difference. The return value is the 3712 empty string. 3713 """ 3714 return self.sash("coord", index) 3715 3716 def sash_mark(self, index): 3717 """Records x and y for the sash given by index; 3718 3719 Used in conjunction with later dragto commands to move the sash. 3720 """ 3721 return self.sash("mark", index) 3722 3723 def sash_place(self, index, x, y): 3724 """Place the sash given by index at the given coordinates 3725 """ 3726 return self.sash("place", index, x, y) 3727 3728 def panecget(self, child, option): 3729 """Query a management option for window. 3730 3731 Option may be any value allowed by the paneconfigure subcommand 3732 """ 3733 return self.tk.call( 3734 (self._w, 'panecget') + (child, '-'+option)) 3735 3736 def paneconfigure(self, tagOrId, cnf=None, **kw): 3737 """Query or modify the management options for window. 3738 3739 If no option is specified, returns a list describing all 3740 of the available options for pathName. If option is 3741 specified with no value, then the command returns a list 3742 describing the one named option (this list will be identical 3743 to the corresponding sublist of the value returned if no 3744 option is specified). If one or more option-value pairs are 3745 specified, then the command modifies the given widget 3746 option(s) to have the given value(s); in this case the 3747 command returns an empty string. The following options 3748 are supported: 3749 3750 after window 3751 Insert the window after the window specified. window 3752 should be the name of a window already managed by pathName. 3753 before window 3754 Insert the window before the window specified. window 3755 should be the name of a window already managed by pathName. 3756 height size 3757 Specify a height for the window. The height will be the 3758 outer dimension of the window including its border, if 3759 any. If size is an empty string, or if -height is not 3760 specified, then the height requested internally by the 3761 window will be used initially; the height may later be 3762 adjusted by the movement of sashes in the panedwindow. 3763 Size may be any value accepted by Tk_GetPixels. 3764 minsize n 3765 Specifies that the size of the window cannot be made 3766 less than n. This constraint only affects the size of 3767 the widget in the paned dimension -- the x dimension 3768 for horizontal panedwindows, the y dimension for 3769 vertical panedwindows. May be any value accepted by 3770 Tk_GetPixels. 3771 padx n 3772 Specifies a non-negative value indicating how much 3773 extra space to leave on each side of the window in 3774 the X-direction. The value may have any of the forms 3775 accepted by Tk_GetPixels. 3776 pady n 3777 Specifies a non-negative value indicating how much 3778 extra space to leave on each side of the window in 3779 the Y-direction. The value may have any of the forms 3780 accepted by Tk_GetPixels. 3781 sticky style 3782 If a window's pane is larger than the requested 3783 dimensions of the window, this option may be used 3784 to position (or stretch) the window within its pane. 3785 Style is a string that contains zero or more of the 3786 characters n, s, e or w. The string can optionally 3787 contains spaces or commas, but they are ignored. Each 3788 letter refers to a side (north, south, east, or west) 3789 that the window will "stick" to. If both n and s 3790 (or e and w) are specified, the window will be 3791 stretched to fill the entire height (or width) of 3792 its cavity. 3793 width size 3794 Specify a width for the window. The width will be 3795 the outer dimension of the window including its 3796 border, if any. If size is an empty string, or 3797 if -width is not specified, then the width requested 3798 internally by the window will be used initially; the 3799 width may later be adjusted by the movement of sashes 3800 in the panedwindow. Size may be any value accepted by 3801 Tk_GetPixels. 3802 3803 """ 3804 if cnf is None and not kw: 3805 return self._getconfigure(self._w, 'paneconfigure', tagOrId) 3806 if type(cnf) == StringType and not kw: 3807 return self._getconfigure1( 3808 self._w, 'paneconfigure', tagOrId, '-'+cnf) 3809 self.tk.call((self._w, 'paneconfigure', tagOrId) + 3810 self._options(cnf, kw)) 3811 paneconfig = paneconfigure 3812 3813 def panes(self): 3814 """Returns an ordered list of the child panes.""" 3815 return self.tk.splitlist(self.tk.call(self._w, 'panes')) 3816 3817###################################################################### 3818# Extensions: 3819 3820class Studbutton(Button): 3821 def __init__(self, master=None, cnf={}, **kw): 3822 Widget.__init__(self, master, 'studbutton', cnf, kw) 3823 self.bind('<Any-Enter>', self.tkButtonEnter) 3824 self.bind('<Any-Leave>', self.tkButtonLeave) 3825 self.bind('<1>', self.tkButtonDown) 3826 self.bind('<ButtonRelease-1>', self.tkButtonUp) 3827 3828class Tributton(Button): 3829 def __init__(self, master=None, cnf={}, **kw): 3830 Widget.__init__(self, master, 'tributton', cnf, kw) 3831 self.bind('<Any-Enter>', self.tkButtonEnter) 3832 self.bind('<Any-Leave>', self.tkButtonLeave) 3833 self.bind('<1>', self.tkButtonDown) 3834 self.bind('<ButtonRelease-1>', self.tkButtonUp) 3835 self['fg'] = self['bg'] 3836 self['activebackground'] = self['bg'] 3837 3838###################################################################### 3839# Test: 3840 3841def _test(): 3842 root = Tk() 3843 text = "This is Tcl/Tk version %s" % TclVersion 3844 if TclVersion >= 8.1: 3845 try: 3846 text = text + unicode("\nThis should be a cedilla: \347", 3847 "iso-8859-1") 3848 except NameError: 3849 pass # no unicode support 3850 label = Label(root, text=text) 3851 label.pack() 3852 test = Button(root, text="Click me!", 3853 command=lambda root=root: root.test.configure( 3854 text="[%s]" % root.test['text'])) 3855 test.pack() 3856 root.test = test 3857 quit = Button(root, text="QUIT", command=root.destroy) 3858 quit.pack() 3859 # The following three commands are needed so the window pops 3860 # up on top on Windows... 3861 root.iconify() 3862 root.update() 3863 root.deiconify() 3864 root.mainloop() 3865 3866if __name__ == '__main__': 3867 _test() 3868