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