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