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