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