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