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