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