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 1 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