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