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