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