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