Path: blob/main/Sage_framework/files/tkinter/__init__.py
242 views
"""Wrapper functions for Tcl/Tk.12Tkinter provides classes which allow the display, positioning and3control of widgets. Toplevel widgets are Tk and Toplevel. Other4widgets are Frame, Label, Entry, Text, Canvas, Button, Radiobutton,5Checkbutton, Scale, Listbox, Scrollbar, OptionMenu, Spinbox6LabelFrame and PanedWindow.78Properties of the widgets are specified with keyword arguments.9Keyword arguments have the same name as the corresponding resource10under Tk.1112Widgets are positioned with one of the geometry managers Place, Pack13or Grid. These managers can be called with methods place, pack, grid14available in every Widget.1516Actions are bound to events by resources (e.g. keyword argument17command) or with the method bind.1819Example (Hello, World):20import tkinter21from tkinter.constants import *22tk = tkinter.Tk()23frame = tkinter.Frame(tk, relief=RIDGE, borderwidth=2)24frame.pack(fill=BOTH,expand=1)25label = tkinter.Label(frame, text="Hello, World")26label.pack(fill=X, expand=1)27button = tkinter.Button(frame,text="Exit",command=tk.destroy)28button.pack(side=BOTTOM)29tk.mainloop()30"""3132import collections33import enum34import sys35import types3637import _tkinter # If this fails your Python may not be configured for Tk38TclError = _tkinter.TclError39from tkinter.constants import *40import re4142wantobjects = 143_debug = False # set to True to print executed Tcl/Tk commands4445TkVersion = float(_tkinter.TK_VERSION)46TclVersion = float(_tkinter.TCL_VERSION)4748READABLE = _tkinter.READABLE49WRITABLE = _tkinter.WRITABLE50EXCEPTION = _tkinter.EXCEPTION515253_magic_re = re.compile(r'([\\{}])')54_space_re = re.compile(r'([\s])', re.ASCII)555657def _join(value):58"""Internal function."""59return ' '.join(map(_stringify, value))606162def _stringify(value):63"""Internal function."""64if isinstance(value, (list, tuple)):65if len(value) == 1:66value = _stringify(value[0])67if _magic_re.search(value):68value = '{%s}' % value69else:70value = '{%s}' % _join(value)71else:72if isinstance(value, bytes):73value = str(value, 'latin1')74else:75value = str(value)76if not value:77value = '{}'78elif _magic_re.search(value):79# add '\' before special characters and spaces80value = _magic_re.sub(r'\\\1', value)81value = value.replace('\n', r'\n')82value = _space_re.sub(r'\\\1', value)83if value[0] == '"':84value = '\\' + value85elif value[0] == '"' or _space_re.search(value):86value = '{%s}' % value87return value888990def _flatten(seq):91"""Internal function."""92res = ()93for item in seq:94if isinstance(item, (tuple, list)):95res = res + _flatten(item)96elif item is not None:97res = res + (item,)98return res99100101try: _flatten = _tkinter._flatten102except AttributeError: pass103104105def _cnfmerge(cnfs):106"""Internal function."""107if isinstance(cnfs, dict):108return cnfs109elif isinstance(cnfs, (type(None), str)):110return cnfs111else:112cnf = {}113for c in _flatten(cnfs):114try:115cnf.update(c)116except (AttributeError, TypeError) as msg:117print("_cnfmerge: fallback due to:", msg)118for k, v in c.items():119cnf[k] = v120return cnf121122123try: _cnfmerge = _tkinter._cnfmerge124except AttributeError: pass125126127def _splitdict(tk, v, cut_minus=True, conv=None):128"""Return a properly formatted dict built from Tcl list pairs.129130If cut_minus is True, the supposed '-' prefix will be removed from131keys. If conv is specified, it is used to convert values.132133Tcl list is expected to contain an even number of elements.134"""135t = tk.splitlist(v)136if len(t) % 2:137raise RuntimeError('Tcl list representing a dict is expected '138'to contain an even number of elements')139it = iter(t)140dict = {}141for key, value in zip(it, it):142key = str(key)143if cut_minus and key[0] == '-':144key = key[1:]145if conv:146value = conv(value)147dict[key] = value148return dict149150class _VersionInfoType(collections.namedtuple('_VersionInfoType',151('major', 'minor', 'micro', 'releaselevel', 'serial'))):152def __str__(self):153if self.releaselevel == 'final':154return f'{self.major}.{self.minor}.{self.micro}'155else:156return f'{self.major}.{self.minor}{self.releaselevel[0]}{self.serial}'157158def _parse_version(version):159import re160m = re.fullmatch(r'(\d+)\.(\d+)([ab.])(\d+)', version)161major, minor, releaselevel, serial = m.groups()162major, minor, serial = int(major), int(minor), int(serial)163if releaselevel == '.':164micro = serial165serial = 0166releaselevel = 'final'167else:168micro = 0169releaselevel = {'a': 'alpha', 'b': 'beta'}[releaselevel]170return _VersionInfoType(major, minor, micro, releaselevel, serial)171172173@enum._simple_enum(enum.StrEnum)174class EventType:175KeyPress = '2'176Key = KeyPress177KeyRelease = '3'178ButtonPress = '4'179Button = ButtonPress180ButtonRelease = '5'181Motion = '6'182Enter = '7'183Leave = '8'184FocusIn = '9'185FocusOut = '10'186Keymap = '11' # undocumented187Expose = '12'188GraphicsExpose = '13' # undocumented189NoExpose = '14' # undocumented190Visibility = '15'191Create = '16'192Destroy = '17'193Unmap = '18'194Map = '19'195MapRequest = '20'196Reparent = '21'197Configure = '22'198ConfigureRequest = '23'199Gravity = '24'200ResizeRequest = '25'201Circulate = '26'202CirculateRequest = '27'203Property = '28'204SelectionClear = '29' # undocumented205SelectionRequest = '30' # undocumented206Selection = '31' # undocumented207Colormap = '32'208ClientMessage = '33' # undocumented209Mapping = '34' # undocumented210VirtualEvent = '35' # undocumented211Activate = '36'212Deactivate = '37'213MouseWheel = '38'214215216class Event:217"""Container for the properties of an event.218219Instances of this type are generated if one of the following events occurs:220221KeyPress, KeyRelease - for keyboard events222ButtonPress, ButtonRelease, Motion, Enter, Leave, MouseWheel - for mouse events223Visibility, Unmap, Map, Expose, FocusIn, FocusOut, Circulate,224Colormap, Gravity, Reparent, Property, Destroy, Activate,225Deactivate - for window events.226227If a callback function for one of these events is registered228using bind, bind_all, bind_class, or tag_bind, the callback is229called with an Event as first argument. It will have the230following attributes (in braces are the event types for which231the attribute is valid):232233serial - serial number of event234num - mouse button pressed (ButtonPress, ButtonRelease)235focus - whether the window has the focus (Enter, Leave)236height - height of the exposed window (Configure, Expose)237width - width of the exposed window (Configure, Expose)238keycode - keycode of the pressed key (KeyPress, KeyRelease)239state - state of the event as a number (ButtonPress, ButtonRelease,240Enter, KeyPress, KeyRelease,241Leave, Motion)242state - state as a string (Visibility)243time - when the event occurred244x - x-position of the mouse245y - y-position of the mouse246x_root - x-position of the mouse on the screen247(ButtonPress, ButtonRelease, KeyPress, KeyRelease, Motion)248y_root - y-position of the mouse on the screen249(ButtonPress, ButtonRelease, KeyPress, KeyRelease, Motion)250char - pressed character (KeyPress, KeyRelease)251send_event - see X/Windows documentation252keysym - keysym of the event as a string (KeyPress, KeyRelease)253keysym_num - keysym of the event as a number (KeyPress, KeyRelease)254type - type of the event as a number255widget - widget in which the event occurred256delta - delta of wheel movement (MouseWheel)257"""258259def __repr__(self):260attrs = {k: v for k, v in self.__dict__.items() if v != '??'}261if not self.char:262del attrs['char']263elif self.char != '??':264attrs['char'] = repr(self.char)265if not getattr(self, 'send_event', True):266del attrs['send_event']267if self.state == 0:268del attrs['state']269elif isinstance(self.state, int):270state = self.state271mods = ('Shift', 'Lock', 'Control',272'Mod1', 'Mod2', 'Mod3', 'Mod4', 'Mod5',273'Button1', 'Button2', 'Button3', 'Button4', 'Button5')274s = []275for i, n in enumerate(mods):276if state & (1 << i):277s.append(n)278state = state & ~((1<< len(mods)) - 1)279if state or not s:280s.append(hex(state))281attrs['state'] = '|'.join(s)282if self.delta == 0:283del attrs['delta']284# widget usually is known285# serial and time are not very interesting286# keysym_num duplicates keysym287# x_root and y_root mostly duplicate x and y288keys = ('send_event',289'state', 'keysym', 'keycode', 'char',290'num', 'delta', 'focus',291'x', 'y', 'width', 'height')292return '<%s event%s>' % (293getattr(self.type, 'name', self.type),294''.join(' %s=%s' % (k, attrs[k]) for k in keys if k in attrs)295)296297__class_getitem__ = classmethod(types.GenericAlias)298299300_support_default_root = True301_default_root = None302303304def NoDefaultRoot():305"""Inhibit setting of default root window.306307Call this function to inhibit that the first instance of308Tk is used for windows without an explicit parent window.309"""310global _support_default_root, _default_root311_support_default_root = False312# Delete, so any use of _default_root will immediately raise an exception.313# Rebind before deletion, so repeated calls will not fail.314_default_root = None315del _default_root316317318def _get_default_root(what=None):319if not _support_default_root:320raise RuntimeError("No master specified and tkinter is "321"configured to not support default root")322if _default_root is None:323if what:324raise RuntimeError(f"Too early to {what}: no default root window")325root = Tk()326assert _default_root is root327return _default_root328329330def _get_temp_root():331global _support_default_root332if not _support_default_root:333raise RuntimeError("No master specified and tkinter is "334"configured to not support default root")335root = _default_root336if root is None:337assert _support_default_root338_support_default_root = False339root = Tk()340_support_default_root = True341assert _default_root is None342root.withdraw()343root._temporary = True344return root345346347def _destroy_temp_root(master):348if getattr(master, '_temporary', False):349try:350master.destroy()351except TclError:352pass353354355def _tkerror(err):356"""Internal function."""357pass358359360def _exit(code=0):361"""Internal function. Calling it will raise the exception SystemExit."""362try:363code = int(code)364except ValueError:365pass366raise SystemExit(code)367368369_varnum = 0370371372class Variable:373"""Class to define value holders for e.g. buttons.374375Subclasses StringVar, IntVar, DoubleVar, BooleanVar are specializations376that constrain the type of the value returned from get()."""377_default = ""378_tk = None379_tclCommands = None380381def __init__(self, master=None, value=None, name=None):382"""Construct a variable383384MASTER can be given as master widget.385VALUE is an optional value (defaults to "")386NAME is an optional Tcl name (defaults to PY_VARnum).387388If NAME matches an existing variable and VALUE is omitted389then the existing value is retained.390"""391# check for type of NAME parameter to override weird error message392# raised from Modules/_tkinter.c:SetVar like:393# TypeError: setvar() takes exactly 3 arguments (2 given)394if name is not None and not isinstance(name, str):395raise TypeError("name must be a string")396global _varnum397if master is None:398master = _get_default_root('create variable')399self._root = master._root()400self._tk = master.tk401if name:402self._name = name403else:404self._name = 'PY_VAR' + repr(_varnum)405_varnum += 1406if value is not None:407self.initialize(value)408elif not self._tk.getboolean(self._tk.call("info", "exists", self._name)):409self.initialize(self._default)410411def __del__(self):412"""Unset the variable in Tcl."""413if self._tk is None:414return415if self._tk.getboolean(self._tk.call("info", "exists", self._name)):416self._tk.globalunsetvar(self._name)417if self._tclCommands is not None:418for name in self._tclCommands:419self._tk.deletecommand(name)420self._tclCommands = None421422def __str__(self):423"""Return the name of the variable in Tcl."""424return self._name425426def set(self, value):427"""Set the variable to VALUE."""428return self._tk.globalsetvar(self._name, value)429430initialize = set431432def get(self):433"""Return value of variable."""434return self._tk.globalgetvar(self._name)435436def _register(self, callback):437f = CallWrapper(callback, None, self._root).__call__438cbname = repr(id(f))439try:440callback = callback.__func__441except AttributeError:442pass443try:444cbname = cbname + callback.__name__445except AttributeError:446pass447self._tk.createcommand(cbname, f)448if self._tclCommands is None:449self._tclCommands = []450self._tclCommands.append(cbname)451return cbname452453def trace_add(self, mode, callback):454"""Define a trace callback for the variable.455456Mode is one of "read", "write", "unset", or a list or tuple of457such strings.458Callback must be a function which is called when the variable is459read, written or unset.460461Return the name of the callback.462"""463cbname = self._register(callback)464self._tk.call('trace', 'add', 'variable',465self._name, mode, (cbname,))466return cbname467468def trace_remove(self, mode, cbname):469"""Delete the trace callback for a variable.470471Mode is one of "read", "write", "unset" or a list or tuple of472such strings. Must be same as were specified in trace_add().473cbname is the name of the callback returned from trace_add().474"""475self._tk.call('trace', 'remove', 'variable',476self._name, mode, cbname)477for m, ca in self.trace_info():478if self._tk.splitlist(ca)[0] == cbname:479break480else:481self._tk.deletecommand(cbname)482try:483self._tclCommands.remove(cbname)484except ValueError:485pass486487def trace_info(self):488"""Return all trace callback information."""489splitlist = self._tk.splitlist490return [(splitlist(k), v) for k, v in map(splitlist,491splitlist(self._tk.call('trace', 'info', 'variable', self._name)))]492493def trace_variable(self, mode, callback):494"""Define a trace callback for the variable.495496MODE is one of "r", "w", "u" for read, write, undefine.497CALLBACK must be a function which is called when498the variable is read, written or undefined.499500Return the name of the callback.501502This deprecated method wraps a deprecated Tcl method that will503likely be removed in the future. Use trace_add() instead.504"""505# TODO: Add deprecation warning506cbname = self._register(callback)507self._tk.call("trace", "variable", self._name, mode, cbname)508return cbname509510trace = trace_variable511512def trace_vdelete(self, mode, cbname):513"""Delete the trace callback for a variable.514515MODE is one of "r", "w", "u" for read, write, undefine.516CBNAME is the name of the callback returned from trace_variable or trace.517518This deprecated method wraps a deprecated Tcl method that will519likely be removed in the future. Use trace_remove() instead.520"""521# TODO: Add deprecation warning522self._tk.call("trace", "vdelete", self._name, mode, cbname)523cbname = self._tk.splitlist(cbname)[0]524for m, ca in self.trace_info():525if self._tk.splitlist(ca)[0] == cbname:526break527else:528self._tk.deletecommand(cbname)529try:530self._tclCommands.remove(cbname)531except ValueError:532pass533534def trace_vinfo(self):535"""Return all trace callback information.536537This deprecated method wraps a deprecated Tcl method that will538likely be removed in the future. Use trace_info() instead.539"""540# TODO: Add deprecation warning541return [self._tk.splitlist(x) for x in self._tk.splitlist(542self._tk.call("trace", "vinfo", self._name))]543544def __eq__(self, other):545if not isinstance(other, Variable):546return NotImplemented547return (self._name == other._name548and self.__class__.__name__ == other.__class__.__name__549and self._tk == other._tk)550551552class StringVar(Variable):553"""Value holder for strings variables."""554_default = ""555556def __init__(self, master=None, value=None, name=None):557"""Construct a string variable.558559MASTER can be given as master widget.560VALUE is an optional value (defaults to "")561NAME is an optional Tcl name (defaults to PY_VARnum).562563If NAME matches an existing variable and VALUE is omitted564then the existing value is retained.565"""566Variable.__init__(self, master, value, name)567568def get(self):569"""Return value of variable as string."""570value = self._tk.globalgetvar(self._name)571if isinstance(value, str):572return value573return str(value)574575576class IntVar(Variable):577"""Value holder for integer variables."""578_default = 0579580def __init__(self, master=None, value=None, name=None):581"""Construct an integer variable.582583MASTER can be given as master widget.584VALUE is an optional value (defaults to 0)585NAME is an optional Tcl name (defaults to PY_VARnum).586587If NAME matches an existing variable and VALUE is omitted588then the existing value is retained.589"""590Variable.__init__(self, master, value, name)591592def get(self):593"""Return the value of the variable as an integer."""594value = self._tk.globalgetvar(self._name)595try:596return self._tk.getint(value)597except (TypeError, TclError):598return int(self._tk.getdouble(value))599600601class DoubleVar(Variable):602"""Value holder for float variables."""603_default = 0.0604605def __init__(self, master=None, value=None, name=None):606"""Construct a float variable.607608MASTER can be given as master widget.609VALUE is an optional value (defaults to 0.0)610NAME is an optional Tcl name (defaults to PY_VARnum).611612If NAME matches an existing variable and VALUE is omitted613then the existing value is retained.614"""615Variable.__init__(self, master, value, name)616617def get(self):618"""Return the value of the variable as a float."""619return self._tk.getdouble(self._tk.globalgetvar(self._name))620621622class BooleanVar(Variable):623"""Value holder for boolean variables."""624_default = False625626def __init__(self, master=None, value=None, name=None):627"""Construct a boolean variable.628629MASTER can be given as master widget.630VALUE is an optional value (defaults to False)631NAME is an optional Tcl name (defaults to PY_VARnum).632633If NAME matches an existing variable and VALUE is omitted634then the existing value is retained.635"""636Variable.__init__(self, master, value, name)637638def set(self, value):639"""Set the variable to VALUE."""640return self._tk.globalsetvar(self._name, self._tk.getboolean(value))641642initialize = set643644def get(self):645"""Return the value of the variable as a bool."""646try:647return self._tk.getboolean(self._tk.globalgetvar(self._name))648except TclError:649raise ValueError("invalid literal for getboolean()")650651652def mainloop(n=0):653"""Run the main loop of Tcl."""654_get_default_root('run the main loop').tk.mainloop(n)655656657getint = int658659getdouble = float660661662def getboolean(s):663"""Convert Tcl object to True or False."""664try:665return _get_default_root('use getboolean()').tk.getboolean(s)666except TclError:667raise ValueError("invalid literal for getboolean()")668669670# Methods defined on both toplevel and interior widgets671672class Misc:673"""Internal class.674675Base class which defines methods common for interior widgets."""676677# used for generating child widget names678_last_child_ids = None679680# XXX font command?681_tclCommands = None682683def destroy(self):684"""Internal function.685686Delete all Tcl commands created for687this widget in the Tcl interpreter."""688if self._tclCommands is not None:689for name in self._tclCommands:690self.tk.deletecommand(name)691self._tclCommands = None692693def deletecommand(self, name):694"""Internal function.695696Delete the Tcl command provided in NAME."""697self.tk.deletecommand(name)698try:699self._tclCommands.remove(name)700except ValueError:701pass702703def tk_strictMotif(self, boolean=None):704"""Set Tcl internal variable, whether the look and feel705should adhere to Motif.706707A parameter of 1 means adhere to Motif (e.g. no color708change if mouse passes over slider).709Returns the set value."""710return self.tk.getboolean(self.tk.call(711'set', 'tk_strictMotif', boolean))712713def tk_bisque(self):714"""Change the color scheme to light brown as used in Tk 3.6 and before."""715self.tk.call('tk_bisque')716717def tk_setPalette(self, *args, **kw):718"""Set a new color scheme for all widget elements.719720A single color as argument will cause that all colors of Tk721widget elements are derived from this.722Alternatively several keyword parameters and its associated723colors can be given. The following keywords are valid:724activeBackground, foreground, selectColor,725activeForeground, highlightBackground, selectBackground,726background, highlightColor, selectForeground,727disabledForeground, insertBackground, troughColor."""728self.tk.call(('tk_setPalette',)729+ _flatten(args) + _flatten(list(kw.items())))730731def wait_variable(self, name='PY_VAR'):732"""Wait until the variable is modified.733734A parameter of type IntVar, StringVar, DoubleVar or735BooleanVar must be given."""736self.tk.call('tkwait', 'variable', name)737waitvar = wait_variable # XXX b/w compat738739def wait_window(self, window=None):740"""Wait until a WIDGET is destroyed.741742If no parameter is given self is used."""743if window is None:744window = self745self.tk.call('tkwait', 'window', window._w)746747def wait_visibility(self, window=None):748"""Wait until the visibility of a WIDGET changes749(e.g. it appears).750751If no parameter is given self is used."""752if window is None:753window = self754self.tk.call('tkwait', 'visibility', window._w)755756def setvar(self, name='PY_VAR', value='1'):757"""Set Tcl variable NAME to VALUE."""758self.tk.setvar(name, value)759760def getvar(self, name='PY_VAR'):761"""Return value of Tcl variable NAME."""762return self.tk.getvar(name)763764def getint(self, s):765try:766return self.tk.getint(s)767except TclError as exc:768raise ValueError(str(exc))769770def getdouble(self, s):771try:772return self.tk.getdouble(s)773except TclError as exc:774raise ValueError(str(exc))775776def getboolean(self, s):777"""Return a boolean value for Tcl boolean values true and false given as parameter."""778try:779return self.tk.getboolean(s)780except TclError:781raise ValueError("invalid literal for getboolean()")782783def focus_set(self):784"""Direct input focus to this widget.785786If the application currently does not have the focus787this widget will get the focus if the application gets788the focus through the window manager."""789self.tk.call('focus', self._w)790focus = focus_set # XXX b/w compat?791792def focus_force(self):793"""Direct input focus to this widget even if the794application does not have the focus. Use with795caution!"""796self.tk.call('focus', '-force', self._w)797798def focus_get(self):799"""Return the widget which has currently the focus in the800application.801802Use focus_displayof to allow working with several803displays. Return None if application does not have804the focus."""805name = self.tk.call('focus')806if name == 'none' or not name: return None807return self._nametowidget(name)808809def focus_displayof(self):810"""Return the widget which has currently the focus on the811display where this widget is located.812813Return None if the application does not have the focus."""814name = self.tk.call('focus', '-displayof', self._w)815if name == 'none' or not name: return None816return self._nametowidget(name)817818def focus_lastfor(self):819"""Return the widget which would have the focus if top level820for this widget gets the focus from the window manager."""821name = self.tk.call('focus', '-lastfor', self._w)822if name == 'none' or not name: return None823return self._nametowidget(name)824825def tk_focusFollowsMouse(self):826"""The widget under mouse will get automatically focus. Can not827be disabled easily."""828self.tk.call('tk_focusFollowsMouse')829830def tk_focusNext(self):831"""Return the next widget in the focus order which follows832widget which has currently the focus.833834The focus order first goes to the next child, then to835the children of the child recursively and then to the836next sibling which is higher in the stacking order. A837widget is omitted if it has the takefocus resource set838to 0."""839name = self.tk.call('tk_focusNext', self._w)840if not name: return None841return self._nametowidget(name)842843def tk_focusPrev(self):844"""Return previous widget in the focus order. See tk_focusNext for details."""845name = self.tk.call('tk_focusPrev', self._w)846if not name: return None847return self._nametowidget(name)848849def after(self, ms, func=None, *args):850"""Call function once after given time.851852MS specifies the time in milliseconds. FUNC gives the853function which shall be called. Additional parameters854are given as parameters to the function call. Return855identifier to cancel scheduling with after_cancel."""856if func is None:857# I'd rather use time.sleep(ms*0.001)858self.tk.call('after', ms)859return None860else:861def callit():862try:863func(*args)864finally:865try:866self.deletecommand(name)867except TclError:868pass869try:870callit.__name__ = func.__name__871except AttributeError:872# Required for callable classes (bpo-44404)873callit.__name__ = type(func).__name__874name = self._register(callit)875return self.tk.call('after', ms, name)876877def after_idle(self, func, *args):878"""Call FUNC once if the Tcl main loop has no event to879process.880881Return an identifier to cancel the scheduling with882after_cancel."""883return self.after('idle', func, *args)884885def after_cancel(self, id):886"""Cancel scheduling of function identified with ID.887888Identifier returned by after or after_idle must be889given as first parameter.890"""891if not id:892raise ValueError('id must be a valid identifier returned from '893'after or after_idle')894try:895data = self.tk.call('after', 'info', id)896script = self.tk.splitlist(data)[0]897self.deletecommand(script)898except TclError:899pass900self.tk.call('after', 'cancel', id)901902def after_info(self, id=None):903"""Return information about existing event handlers.904905With no argument, return a tuple of the identifiers for all existing906event handlers created by the after and after_idle commands for this907interpreter. If id is supplied, it specifies an existing handler; id908must have been the return value from some previous call to after or909after_idle and it must not have triggered yet or been canceled. If the910id doesn't exist, a TclError is raised. Otherwise, the return value is911a tuple containing (script, type) where script is a reference to the912function to be called by the event handler and type is either 'idle'913or 'timer' to indicate what kind of event handler it is.914"""915return self.tk.splitlist(self.tk.call('after', 'info', id))916917def bell(self, displayof=0):918"""Ring a display's bell."""919self.tk.call(('bell',) + self._displayof(displayof))920921def tk_busy_cget(self, option):922"""Return the value of busy configuration option.923924The widget must have been previously made busy by925tk_busy_hold(). Option may have any of the values accepted by926tk_busy_hold().927"""928return self.tk.call('tk', 'busy', 'cget', self._w, '-'+option)929busy_cget = tk_busy_cget930931def tk_busy_configure(self, cnf=None, **kw):932"""Query or modify the busy configuration options.933934The widget must have been previously made busy by935tk_busy_hold(). Options may have any of the values accepted by936tk_busy_hold().937938Please note that the option database is referenced by the widget939name or class. For example, if a Frame widget with name "frame"940is to be made busy, the busy cursor can be specified for it by941either call:942943w.option_add('*frame.busyCursor', 'gumby')944w.option_add('*Frame.BusyCursor', 'gumby')945"""946if kw:947cnf = _cnfmerge((cnf, kw))948elif cnf:949cnf = _cnfmerge(cnf)950if cnf is None:951return self._getconfigure(952'tk', 'busy', 'configure', self._w)953if isinstance(cnf, str):954return self._getconfigure1(955'tk', 'busy', 'configure', self._w, '-'+cnf)956self.tk.call('tk', 'busy', 'configure', self._w, *self._options(cnf))957busy_config = busy_configure = tk_busy_config = tk_busy_configure958959def tk_busy_current(self, pattern=None):960"""Return a list of widgets that are currently busy.961962If a pattern is given, only busy widgets whose path names match963a pattern are returned.964"""965return [self._nametowidget(x) for x in966self.tk.splitlist(self.tk.call(967'tk', 'busy', 'current', pattern))]968busy_current = tk_busy_current969970def tk_busy_forget(self):971"""Make this widget no longer busy.972973User events will again be received by the widget.974"""975self.tk.call('tk', 'busy', 'forget', self._w)976busy_forget = tk_busy_forget977978def tk_busy_hold(self, **kw):979"""Make this widget appear busy.980981The specified widget and its descendants will be blocked from982user interactions. Normally update() should be called983immediately afterward to insure that the hold operation is in984effect before the application starts its processing.985986The only supported configuration option is:987988cursor: the cursor to be displayed when the widget is made989busy.990"""991self.tk.call('tk', 'busy', 'hold', self._w, *self._options(kw))992busy = busy_hold = tk_busy = tk_busy_hold993994def tk_busy_status(self):995"""Return True if the widget is busy, False otherwise."""996return self.tk.getboolean(self.tk.call(997'tk', 'busy', 'status', self._w))998busy_status = tk_busy_status9991000# Clipboard handling:1001def clipboard_get(self, **kw):1002"""Retrieve data from the clipboard on window's display.10031004The window keyword defaults to the root window of the Tkinter1005application.10061007The type keyword specifies the form in which the data is1008to be returned and should be an atom name such as STRING1009or FILE_NAME. Type defaults to STRING, except on X11, where the default1010is to try UTF8_STRING and fall back to STRING.10111012This command is equivalent to:10131014selection_get(CLIPBOARD)1015"""1016if 'type' not in kw and self._windowingsystem == 'x11':1017try:1018kw['type'] = 'UTF8_STRING'1019return self.tk.call(('clipboard', 'get') + self._options(kw))1020except TclError:1021del kw['type']1022return self.tk.call(('clipboard', 'get') + self._options(kw))10231024def clipboard_clear(self, **kw):1025"""Clear the data in the Tk clipboard.10261027A widget specified for the optional displayof keyword1028argument specifies the target display."""1029if 'displayof' not in kw: kw['displayof'] = self._w1030self.tk.call(('clipboard', 'clear') + self._options(kw))10311032def clipboard_append(self, string, **kw):1033"""Append STRING to the Tk clipboard.10341035A widget specified at the optional displayof keyword1036argument specifies the target display. The clipboard1037can be retrieved with selection_get."""1038if 'displayof' not in kw: kw['displayof'] = self._w1039self.tk.call(('clipboard', 'append') + self._options(kw)1040+ ('--', string))1041# XXX grab current w/o window argument10421043def grab_current(self):1044"""Return widget which has currently the grab in this application1045or None."""1046name = self.tk.call('grab', 'current', self._w)1047if not name: return None1048return self._nametowidget(name)10491050def grab_release(self):1051"""Release grab for this widget if currently set."""1052self.tk.call('grab', 'release', self._w)10531054def grab_set(self):1055"""Set grab for this widget.10561057A grab directs all events to this and descendant1058widgets in the application."""1059self.tk.call('grab', 'set', self._w)10601061def grab_set_global(self):1062"""Set global grab for this widget.10631064A global grab directs all events to this and1065descendant widgets on the display. Use with caution -1066other applications do not get events anymore."""1067self.tk.call('grab', 'set', '-global', self._w)10681069def grab_status(self):1070"""Return None, "local" or "global" if this widget has1071no, a local or a global grab."""1072status = self.tk.call('grab', 'status', self._w)1073if status == 'none': status = None1074return status10751076def option_add(self, pattern, value, priority = None):1077"""Set a VALUE (second parameter) for an option1078PATTERN (first parameter).10791080An optional third parameter gives the numeric priority1081(defaults to 80)."""1082self.tk.call('option', 'add', pattern, value, priority)10831084def option_clear(self):1085"""Clear the option database.10861087It will be reloaded if option_add is called."""1088self.tk.call('option', 'clear')10891090def option_get(self, name, className):1091"""Return the value for an option NAME for this widget1092with CLASSNAME.10931094Values with higher priority override lower values."""1095return self.tk.call('option', 'get', self._w, name, className)10961097def option_readfile(self, fileName, priority = None):1098"""Read file FILENAME into the option database.10991100An optional second parameter gives the numeric1101priority."""1102self.tk.call('option', 'readfile', fileName, priority)11031104def selection_clear(self, **kw):1105"""Clear the current X selection."""1106if 'displayof' not in kw: kw['displayof'] = self._w1107self.tk.call(('selection', 'clear') + self._options(kw))11081109def selection_get(self, **kw):1110"""Return the contents of the current X selection.11111112A keyword parameter selection specifies the name of1113the selection and defaults to PRIMARY. A keyword1114parameter displayof specifies a widget on the display1115to use. A keyword parameter type specifies the form of data to be1116fetched, defaulting to STRING except on X11, where UTF8_STRING is tried1117before STRING."""1118if 'displayof' not in kw: kw['displayof'] = self._w1119if 'type' not in kw and self._windowingsystem == 'x11':1120try:1121kw['type'] = 'UTF8_STRING'1122return self.tk.call(('selection', 'get') + self._options(kw))1123except TclError:1124del kw['type']1125return self.tk.call(('selection', 'get') + self._options(kw))11261127def selection_handle(self, command, **kw):1128"""Specify a function COMMAND to call if the X1129selection owned by this widget is queried by another1130application.11311132This function must return the contents of the1133selection. The function will be called with the1134arguments OFFSET and LENGTH which allows the chunking1135of very long selections. The following keyword1136parameters can be provided:1137selection - name of the selection (default PRIMARY),1138type - type of the selection (e.g. STRING, FILE_NAME)."""1139name = self._register(command)1140self.tk.call(('selection', 'handle') + self._options(kw)1141+ (self._w, name))11421143def selection_own(self, **kw):1144"""Become owner of X selection.11451146A keyword parameter selection specifies the name of1147the selection (default PRIMARY)."""1148self.tk.call(('selection', 'own') +1149self._options(kw) + (self._w,))11501151def selection_own_get(self, **kw):1152"""Return owner of X selection.11531154The following keyword parameter can1155be provided:1156selection - name of the selection (default PRIMARY),1157type - type of the selection (e.g. STRING, FILE_NAME)."""1158if 'displayof' not in kw: kw['displayof'] = self._w1159name = self.tk.call(('selection', 'own') + self._options(kw))1160if not name: return None1161return self._nametowidget(name)11621163def send(self, interp, cmd, *args):1164"""Send Tcl command CMD to different interpreter INTERP to be executed."""1165return self.tk.call(('send', interp, cmd) + args)11661167def lower(self, belowThis=None):1168"""Lower this widget in the stacking order."""1169self.tk.call('lower', self._w, belowThis)11701171def tkraise(self, aboveThis=None):1172"""Raise this widget in the stacking order."""1173self.tk.call('raise', self._w, aboveThis)11741175lift = tkraise11761177def info_patchlevel(self):1178"""Returns the exact version of the Tcl library."""1179patchlevel = self.tk.call('info', 'patchlevel')1180return _parse_version(patchlevel)11811182def winfo_atom(self, name, displayof=0):1183"""Return integer which represents atom NAME."""1184args = ('winfo', 'atom') + self._displayof(displayof) + (name,)1185return self.tk.getint(self.tk.call(args))11861187def winfo_atomname(self, id, displayof=0):1188"""Return name of atom with identifier ID."""1189args = ('winfo', 'atomname') \1190+ self._displayof(displayof) + (id,)1191return self.tk.call(args)11921193def winfo_cells(self):1194"""Return number of cells in the colormap for this widget."""1195return self.tk.getint(1196self.tk.call('winfo', 'cells', self._w))11971198def winfo_children(self):1199"""Return a list of all widgets which are children of this widget."""1200result = []1201for child in self.tk.splitlist(1202self.tk.call('winfo', 'children', self._w)):1203try:1204# Tcl sometimes returns extra windows, e.g. for1205# menus; those need to be skipped1206result.append(self._nametowidget(child))1207except KeyError:1208pass1209return result12101211def winfo_class(self):1212"""Return window class name of this widget."""1213return self.tk.call('winfo', 'class', self._w)12141215def winfo_colormapfull(self):1216"""Return True if at the last color request the colormap was full."""1217return self.tk.getboolean(1218self.tk.call('winfo', 'colormapfull', self._w))12191220def winfo_containing(self, rootX, rootY, displayof=0):1221"""Return the widget which is at the root coordinates ROOTX, ROOTY."""1222args = ('winfo', 'containing') \1223+ self._displayof(displayof) + (rootX, rootY)1224name = self.tk.call(args)1225if not name: return None1226return self._nametowidget(name)12271228def winfo_depth(self):1229"""Return the number of bits per pixel."""1230return self.tk.getint(self.tk.call('winfo', 'depth', self._w))12311232def winfo_exists(self):1233"""Return true if this widget exists."""1234return self.tk.getint(1235self.tk.call('winfo', 'exists', self._w))12361237def winfo_fpixels(self, number):1238"""Return the number of pixels for the given distance NUMBER1239(e.g. "3c") as float."""1240return self.tk.getdouble(self.tk.call(1241'winfo', 'fpixels', self._w, number))12421243def winfo_geometry(self):1244"""Return geometry string for this widget in the form "widthxheight+X+Y"."""1245return self.tk.call('winfo', 'geometry', self._w)12461247def winfo_height(self):1248"""Return height of this widget."""1249return self.tk.getint(1250self.tk.call('winfo', 'height', self._w))12511252def winfo_id(self):1253"""Return identifier ID for this widget."""1254return int(self.tk.call('winfo', 'id', self._w), 0)12551256def winfo_interps(self, displayof=0):1257"""Return the name of all Tcl interpreters for this display."""1258args = ('winfo', 'interps') + self._displayof(displayof)1259return self.tk.splitlist(self.tk.call(args))12601261def winfo_ismapped(self):1262"""Return true if this widget is mapped."""1263return self.tk.getint(1264self.tk.call('winfo', 'ismapped', self._w))12651266def winfo_manager(self):1267"""Return the window manager name for this widget."""1268return self.tk.call('winfo', 'manager', self._w)12691270def winfo_name(self):1271"""Return the name of this widget."""1272return self.tk.call('winfo', 'name', self._w)12731274def winfo_parent(self):1275"""Return the name of the parent of this widget."""1276return self.tk.call('winfo', 'parent', self._w)12771278def winfo_pathname(self, id, displayof=0):1279"""Return the pathname of the widget given by ID."""1280if isinstance(id, int):1281id = hex(id)1282args = ('winfo', 'pathname') \1283+ self._displayof(displayof) + (id,)1284return self.tk.call(args)12851286def winfo_pixels(self, number):1287"""Rounded integer value of winfo_fpixels."""1288return self.tk.getint(1289self.tk.call('winfo', 'pixels', self._w, number))12901291def winfo_pointerx(self):1292"""Return the x coordinate of the pointer on the root window."""1293return self.tk.getint(1294self.tk.call('winfo', 'pointerx', self._w))12951296def winfo_pointerxy(self):1297"""Return a tuple of x and y coordinates of the pointer on the root window."""1298return self._getints(1299self.tk.call('winfo', 'pointerxy', self._w))13001301def winfo_pointery(self):1302"""Return the y coordinate of the pointer on the root window."""1303return self.tk.getint(1304self.tk.call('winfo', 'pointery', self._w))13051306def winfo_reqheight(self):1307"""Return requested height of this widget."""1308return self.tk.getint(1309self.tk.call('winfo', 'reqheight', self._w))13101311def winfo_reqwidth(self):1312"""Return requested width of this widget."""1313return self.tk.getint(1314self.tk.call('winfo', 'reqwidth', self._w))13151316def winfo_rgb(self, color):1317"""Return a tuple of integer RGB values in range(65536) for color in this widget."""1318return self._getints(1319self.tk.call('winfo', 'rgb', self._w, color))13201321def winfo_rootx(self):1322"""Return x coordinate of upper left corner of this widget on the1323root window."""1324return self.tk.getint(1325self.tk.call('winfo', 'rootx', self._w))13261327def winfo_rooty(self):1328"""Return y coordinate of upper left corner of this widget on the1329root window."""1330return self.tk.getint(1331self.tk.call('winfo', 'rooty', self._w))13321333def winfo_screen(self):1334"""Return the screen name of this widget."""1335return self.tk.call('winfo', 'screen', self._w)13361337def winfo_screencells(self):1338"""Return the number of the cells in the colormap of the screen1339of this widget."""1340return self.tk.getint(1341self.tk.call('winfo', 'screencells', self._w))13421343def winfo_screendepth(self):1344"""Return the number of bits per pixel of the root window of the1345screen of this widget."""1346return self.tk.getint(1347self.tk.call('winfo', 'screendepth', self._w))13481349def winfo_screenheight(self):1350"""Return the number of pixels of the height of the screen of this widget1351in pixel."""1352return self.tk.getint(1353self.tk.call('winfo', 'screenheight', self._w))13541355def winfo_screenmmheight(self):1356"""Return the number of pixels of the height of the screen of1357this widget in mm."""1358return self.tk.getint(1359self.tk.call('winfo', 'screenmmheight', self._w))13601361def winfo_screenmmwidth(self):1362"""Return the number of pixels of the width of the screen of1363this widget in mm."""1364return self.tk.getint(1365self.tk.call('winfo', 'screenmmwidth', self._w))13661367def winfo_screenvisual(self):1368"""Return one of the strings directcolor, grayscale, pseudocolor,1369staticcolor, staticgray, or truecolor for the default1370colormodel of this screen."""1371return self.tk.call('winfo', 'screenvisual', self._w)13721373def winfo_screenwidth(self):1374"""Return the number of pixels of the width of the screen of1375this widget in pixel."""1376return self.tk.getint(1377self.tk.call('winfo', 'screenwidth', self._w))13781379def winfo_server(self):1380"""Return information of the X-Server of the screen of this widget in1381the form "XmajorRminor vendor vendorVersion"."""1382return self.tk.call('winfo', 'server', self._w)13831384def winfo_toplevel(self):1385"""Return the toplevel widget of this widget."""1386return self._nametowidget(self.tk.call(1387'winfo', 'toplevel', self._w))13881389def winfo_viewable(self):1390"""Return true if the widget and all its higher ancestors are mapped."""1391return self.tk.getint(1392self.tk.call('winfo', 'viewable', self._w))13931394def winfo_visual(self):1395"""Return one of the strings directcolor, grayscale, pseudocolor,1396staticcolor, staticgray, or truecolor for the1397colormodel of this widget."""1398return self.tk.call('winfo', 'visual', self._w)13991400def winfo_visualid(self):1401"""Return the X identifier for the visual for this widget."""1402return self.tk.call('winfo', 'visualid', self._w)14031404def winfo_visualsavailable(self, includeids=False):1405"""Return a list of all visuals available for the screen1406of this widget.14071408Each item in the list consists of a visual name (see winfo_visual), a1409depth and if includeids is true is given also the X identifier."""1410data = self.tk.call('winfo', 'visualsavailable', self._w,1411'includeids' if includeids else None)1412data = [self.tk.splitlist(x) for x in self.tk.splitlist(data)]1413return [self.__winfo_parseitem(x) for x in data]14141415def __winfo_parseitem(self, t):1416"""Internal function."""1417return t[:1] + tuple(map(self.__winfo_getint, t[1:]))14181419def __winfo_getint(self, x):1420"""Internal function."""1421return int(x, 0)14221423def winfo_vrootheight(self):1424"""Return the height of the virtual root window associated with this1425widget in pixels. If there is no virtual root window return the1426height of the screen."""1427return self.tk.getint(1428self.tk.call('winfo', 'vrootheight', self._w))14291430def winfo_vrootwidth(self):1431"""Return the width of the virtual root window associated with this1432widget in pixel. If there is no virtual root window return the1433width of the screen."""1434return self.tk.getint(1435self.tk.call('winfo', 'vrootwidth', self._w))14361437def winfo_vrootx(self):1438"""Return the x offset of the virtual root relative to the root1439window of the screen of this widget."""1440return self.tk.getint(1441self.tk.call('winfo', 'vrootx', self._w))14421443def winfo_vrooty(self):1444"""Return the y offset of the virtual root relative to the root1445window of the screen of this widget."""1446return self.tk.getint(1447self.tk.call('winfo', 'vrooty', self._w))14481449def winfo_width(self):1450"""Return the width of this widget."""1451return self.tk.getint(1452self.tk.call('winfo', 'width', self._w))14531454def winfo_x(self):1455"""Return the x coordinate of the upper left corner of this widget1456in the parent."""1457return self.tk.getint(1458self.tk.call('winfo', 'x', self._w))14591460def winfo_y(self):1461"""Return the y coordinate of the upper left corner of this widget1462in the parent."""1463return self.tk.getint(1464self.tk.call('winfo', 'y', self._w))14651466def update(self):1467"""Enter event loop until all pending events have been processed by Tcl."""1468self.tk.call('update')14691470def update_idletasks(self):1471"""Enter event loop until all idle callbacks have been called. This1472will update the display of windows but not process events caused by1473the user."""1474self.tk.call('update', 'idletasks')14751476def bindtags(self, tagList=None):1477"""Set or get the list of bindtags for this widget.14781479With no argument return the list of all bindtags associated with1480this widget. With a list of strings as argument the bindtags are1481set to this list. The bindtags determine in which order events are1482processed (see bind)."""1483if tagList is None:1484return self.tk.splitlist(1485self.tk.call('bindtags', self._w))1486else:1487self.tk.call('bindtags', self._w, tagList)14881489def _bind(self, what, sequence, func, add, needcleanup=1):1490"""Internal function."""1491if isinstance(func, str):1492self.tk.call(what + (sequence, func))1493elif func:1494funcid = self._register(func, self._substitute,1495needcleanup)1496cmd = ('%sif {"[%s %s]" == "break"} break\n'1497%1498(add and '+' or '',1499funcid, self._subst_format_str))1500self.tk.call(what + (sequence, cmd))1501return funcid1502elif sequence:1503return self.tk.call(what + (sequence,))1504else:1505return self.tk.splitlist(self.tk.call(what))15061507def bind(self, sequence=None, func=None, add=None):1508"""Bind to this widget at event SEQUENCE a call to function FUNC.15091510SEQUENCE is a string of concatenated event1511patterns. An event pattern is of the form1512<MODIFIER-MODIFIER-TYPE-DETAIL> where MODIFIER is one1513of Control, Mod2, M2, Shift, Mod3, M3, Lock, Mod4, M4,1514Button1, B1, Mod5, M5 Button2, B2, Meta, M, Button3,1515B3, Alt, Button4, B4, Double, Button5, B5 Triple,1516Mod1, M1. TYPE is one of Activate, Enter, Map,1517ButtonPress, Button, Expose, Motion, ButtonRelease1518FocusIn, MouseWheel, Circulate, FocusOut, Property,1519Colormap, Gravity Reparent, Configure, KeyPress, Key,1520Unmap, Deactivate, KeyRelease Visibility, Destroy,1521Leave and DETAIL is the button number for ButtonPress,1522ButtonRelease and DETAIL is the Keysym for KeyPress and1523KeyRelease. Examples are1524<Control-Button-1> for pressing Control and mouse button 1 or1525<Alt-A> for pressing A and the Alt key (KeyPress can be omitted).1526An event pattern can also be a virtual event of the form1527<<AString>> where AString can be arbitrary. This1528event can be generated by event_generate.1529If events are concatenated they must appear shortly1530after each other.15311532FUNC will be called if the event sequence occurs with an1533instance of Event as argument. If the return value of FUNC is1534"break" no further bound function is invoked.15351536An additional boolean parameter ADD specifies whether FUNC will1537be called additionally to the other bound function or whether1538it will replace the previous function.15391540Bind will return an identifier to allow deletion of the bound function with1541unbind without memory leak.15421543If FUNC or SEQUENCE is omitted the bound function or list1544of bound events are returned."""15451546return self._bind(('bind', self._w), sequence, func, add)15471548def unbind(self, sequence, funcid=None):1549"""Unbind for this widget the event SEQUENCE.15501551If FUNCID is given, only unbind the function identified with FUNCID1552and also delete the corresponding Tcl command.15531554Otherwise destroy the current binding for SEQUENCE, leaving SEQUENCE1555unbound.1556"""1557self._unbind(('bind', self._w, sequence), funcid)15581559def _unbind(self, what, funcid=None):1560if funcid is None:1561self.tk.call(*what, '')1562else:1563lines = self.tk.call(what).split('\n')1564prefix = f'if {{"[{funcid} '1565keep = '\n'.join(line for line in lines1566if not line.startswith(prefix))1567if not keep.strip():1568keep = ''1569self.tk.call(*what, keep)1570self.deletecommand(funcid)15711572def bind_all(self, sequence=None, func=None, add=None):1573"""Bind to all widgets at an event SEQUENCE a call to function FUNC.1574An additional boolean parameter ADD specifies whether FUNC will1575be called additionally to the other bound function or whether1576it will replace the previous function. See bind for the return value."""1577return self._root()._bind(('bind', 'all'), sequence, func, add, True)15781579def unbind_all(self, sequence):1580"""Unbind for all widgets for event SEQUENCE all functions."""1581self._root()._unbind(('bind', 'all', sequence))15821583def bind_class(self, className, sequence=None, func=None, add=None):1584"""Bind to widgets with bindtag CLASSNAME at event1585SEQUENCE a call of function FUNC. An additional1586boolean parameter ADD specifies whether FUNC will be1587called additionally to the other bound function or1588whether it will replace the previous function. See bind for1589the return value."""15901591return self._root()._bind(('bind', className), sequence, func, add, True)15921593def unbind_class(self, className, sequence):1594"""Unbind for all widgets with bindtag CLASSNAME for event SEQUENCE1595all functions."""1596self._root()._unbind(('bind', className, sequence))15971598def mainloop(self, n=0):1599"""Call the mainloop of Tk."""1600self.tk.mainloop(n)16011602def quit(self):1603"""Quit the Tcl interpreter. All widgets will be destroyed."""1604self.tk.quit()16051606def _getints(self, string):1607"""Internal function."""1608if string:1609return tuple(map(self.tk.getint, self.tk.splitlist(string)))16101611def _getdoubles(self, string):1612"""Internal function."""1613if string:1614return tuple(map(self.tk.getdouble, self.tk.splitlist(string)))16151616def _getboolean(self, string):1617"""Internal function."""1618if string:1619return self.tk.getboolean(string)16201621def _displayof(self, displayof):1622"""Internal function."""1623if displayof:1624return ('-displayof', displayof)1625if displayof is None:1626return ('-displayof', self._w)1627return ()16281629@property1630def _windowingsystem(self):1631"""Internal function."""1632try:1633return self._root()._windowingsystem_cached1634except AttributeError:1635ws = self._root()._windowingsystem_cached = \1636self.tk.call('tk', 'windowingsystem')1637return ws16381639def _options(self, cnf, kw = None):1640"""Internal function."""1641if kw:1642cnf = _cnfmerge((cnf, kw))1643else:1644cnf = _cnfmerge(cnf)1645res = ()1646for k, v in cnf.items():1647if v is not None:1648if k[-1] == '_': k = k[:-1]1649if callable(v):1650v = self._register(v)1651elif isinstance(v, (tuple, list)):1652nv = []1653for item in v:1654if isinstance(item, int):1655nv.append(str(item))1656elif isinstance(item, str):1657nv.append(_stringify(item))1658else:1659break1660else:1661v = ' '.join(nv)1662res = res + ('-'+k, v)1663return res16641665def nametowidget(self, name):1666"""Return the Tkinter instance of a widget identified by1667its Tcl name NAME."""1668name = str(name).split('.')1669w = self16701671if not name[0]:1672w = w._root()1673name = name[1:]16741675for n in name:1676if not n:1677break1678w = w.children[n]16791680return w16811682_nametowidget = nametowidget16831684def _register(self, func, subst=None, needcleanup=1):1685"""Return a newly created Tcl function. If this1686function is called, the Python function FUNC will1687be executed. An optional function SUBST can1688be given which will be executed before FUNC."""1689f = CallWrapper(func, subst, self).__call__1690name = repr(id(f))1691try:1692func = func.__func__1693except AttributeError:1694pass1695try:1696name = name + func.__name__1697except AttributeError:1698pass1699self.tk.createcommand(name, f)1700if needcleanup:1701if self._tclCommands is None:1702self._tclCommands = []1703self._tclCommands.append(name)1704return name17051706register = _register17071708def _root(self):1709"""Internal function."""1710w = self1711while w.master is not None: w = w.master1712return w1713_subst_format = ('%#', '%b', '%f', '%h', '%k',1714'%s', '%t', '%w', '%x', '%y',1715'%A', '%E', '%K', '%N', '%W', '%T', '%X', '%Y', '%D')1716_subst_format_str = " ".join(_subst_format)17171718def _substitute(self, *args):1719"""Internal function."""1720if len(args) != len(self._subst_format): return args1721getboolean = self.tk.getboolean17221723getint = self.tk.getint1724def getint_event(s):1725"""Tk changed behavior in 8.4.2, returning "??" rather more often."""1726try:1727return getint(s)1728except (ValueError, TclError):1729return s17301731if any(isinstance(s, tuple) for s in args):1732args = [s[0] if isinstance(s, tuple) and len(s) == 1 else s1733for s in args]1734nsign, b, f, h, k, s, t, w, x, y, A, E, K, N, W, T, X, Y, D = args1735# Missing: (a, c, d, m, o, v, B, R)1736e = Event()1737# serial field: valid for all events1738# number of button: ButtonPress and ButtonRelease events only1739# height field: Configure, ConfigureRequest, Create,1740# ResizeRequest, and Expose events only1741# keycode field: KeyPress and KeyRelease events only1742# time field: "valid for events that contain a time field"1743# width field: Configure, ConfigureRequest, Create, ResizeRequest,1744# and Expose events only1745# x field: "valid for events that contain an x field"1746# y field: "valid for events that contain a y field"1747# keysym as decimal: KeyPress and KeyRelease events only1748# x_root, y_root fields: ButtonPress, ButtonRelease, KeyPress,1749# KeyRelease, and Motion events1750e.serial = getint(nsign)1751e.num = getint_event(b)1752try: e.focus = getboolean(f)1753except TclError: pass1754e.height = getint_event(h)1755e.keycode = getint_event(k)1756e.state = getint_event(s)1757e.time = getint_event(t)1758e.width = getint_event(w)1759e.x = getint_event(x)1760e.y = getint_event(y)1761e.char = A1762try: e.send_event = getboolean(E)1763except TclError: pass1764e.keysym = K1765e.keysym_num = getint_event(N)1766try:1767e.type = EventType(T)1768except ValueError:1769try:1770e.type = EventType(str(T)) # can be int1771except ValueError:1772e.type = T1773try:1774e.widget = self._nametowidget(W)1775except KeyError:1776e.widget = W1777e.x_root = getint_event(X)1778e.y_root = getint_event(Y)1779try:1780e.delta = getint(D)1781except (ValueError, TclError):1782e.delta = 01783return (e,)17841785def _report_exception(self):1786"""Internal function."""1787exc, val, tb = sys.exc_info()1788root = self._root()1789root.report_callback_exception(exc, val, tb)17901791def _getconfigure(self, *args):1792"""Call Tcl configure command and return the result as a dict."""1793cnf = {}1794for x in self.tk.splitlist(self.tk.call(*args)):1795x = self.tk.splitlist(x)1796cnf[x[0][1:]] = (x[0][1:],) + x[1:]1797return cnf17981799def _getconfigure1(self, *args):1800x = self.tk.splitlist(self.tk.call(*args))1801return (x[0][1:],) + x[1:]18021803def _configure(self, cmd, cnf, kw):1804"""Internal function."""1805if kw:1806cnf = _cnfmerge((cnf, kw))1807elif cnf:1808cnf = _cnfmerge(cnf)1809if cnf is None:1810return self._getconfigure(_flatten((self._w, cmd)))1811if isinstance(cnf, str):1812return self._getconfigure1(_flatten((self._w, cmd, '-'+cnf)))1813self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))1814# These used to be defined in Widget:18151816def configure(self, cnf=None, **kw):1817"""Configure resources of a widget.18181819The values for resources are specified as keyword1820arguments. To get an overview about1821the allowed keyword arguments call the method keys.1822"""1823return self._configure('configure', cnf, kw)18241825config = configure18261827def cget(self, key):1828"""Return the resource value for a KEY given as string."""1829return self.tk.call(self._w, 'cget', '-' + key)18301831__getitem__ = cget18321833def __setitem__(self, key, value):1834self.configure({key: value})18351836def keys(self):1837"""Return a list of all resource names of this widget."""1838splitlist = self.tk.splitlist1839return [splitlist(x)[0][1:] for x in1840splitlist(self.tk.call(self._w, 'configure'))]18411842def __str__(self):1843"""Return the window path name of this widget."""1844return self._w18451846def __repr__(self):1847return '<%s.%s object %s>' % (1848self.__class__.__module__, self.__class__.__qualname__, self._w)18491850# Pack methods that apply to the master1851_noarg_ = ['_noarg_']18521853def pack_propagate(self, flag=_noarg_):1854"""Set or get the status for propagation of geometry information.18551856A boolean argument specifies whether the geometry information1857of the slaves will determine the size of this widget. If no argument1858is given the current setting will be returned.1859"""1860if flag is Misc._noarg_:1861return self._getboolean(self.tk.call(1862'pack', 'propagate', self._w))1863else:1864self.tk.call('pack', 'propagate', self._w, flag)18651866propagate = pack_propagate18671868def pack_slaves(self):1869"""Return a list of all slaves of this widget1870in its packing order."""1871return [self._nametowidget(x) for x in1872self.tk.splitlist(1873self.tk.call('pack', 'slaves', self._w))]18741875slaves = pack_slaves18761877# Place method that applies to the master1878def place_slaves(self):1879"""Return a list of all slaves of this widget1880in its packing order."""1881return [self._nametowidget(x) for x in1882self.tk.splitlist(1883self.tk.call(1884'place', 'slaves', self._w))]18851886# Grid methods that apply to the master18871888def grid_anchor(self, anchor=None): # new in Tk 8.51889"""The anchor value controls how to place the grid within the1890master when no row/column has any weight.18911892The default anchor is nw."""1893self.tk.call('grid', 'anchor', self._w, anchor)18941895anchor = grid_anchor18961897def grid_bbox(self, column=None, row=None, col2=None, row2=None):1898"""Return a tuple of integer coordinates for the bounding1899box of this widget controlled by the geometry manager grid.19001901If COLUMN, ROW is given the bounding box applies from1902the cell with row and column 0 to the specified1903cell. If COL2 and ROW2 are given the bounding box1904starts at that cell.19051906The returned integers specify the offset of the upper left1907corner in the master widget and the width and height.1908"""1909args = ('grid', 'bbox', self._w)1910if column is not None and row is not None:1911args = args + (column, row)1912if col2 is not None and row2 is not None:1913args = args + (col2, row2)1914return self._getints(self.tk.call(*args)) or None19151916bbox = grid_bbox19171918def _gridconvvalue(self, value):1919if isinstance(value, (str, _tkinter.Tcl_Obj)):1920try:1921svalue = str(value)1922if not svalue:1923return None1924elif '.' in svalue:1925return self.tk.getdouble(svalue)1926else:1927return self.tk.getint(svalue)1928except (ValueError, TclError):1929pass1930return value19311932def _grid_configure(self, command, index, cnf, kw):1933"""Internal function."""1934if isinstance(cnf, str) and not kw:1935if cnf[-1:] == '_':1936cnf = cnf[:-1]1937if cnf[:1] != '-':1938cnf = '-'+cnf1939options = (cnf,)1940else:1941options = self._options(cnf, kw)1942if not options:1943return _splitdict(1944self.tk,1945self.tk.call('grid', command, self._w, index),1946conv=self._gridconvvalue)1947res = self.tk.call(1948('grid', command, self._w, index)1949+ options)1950if len(options) == 1:1951return self._gridconvvalue(res)19521953def grid_columnconfigure(self, index, cnf={}, **kw):1954"""Configure column INDEX of a grid.19551956Valid resources are minsize (minimum size of the column),1957weight (how much does additional space propagate to this column)1958and pad (how much space to let additionally)."""1959return self._grid_configure('columnconfigure', index, cnf, kw)19601961columnconfigure = grid_columnconfigure19621963def grid_location(self, x, y):1964"""Return a tuple of column and row which identify the cell1965at which the pixel at position X and Y inside the master1966widget is located."""1967return self._getints(1968self.tk.call(1969'grid', 'location', self._w, x, y)) or None19701971def grid_propagate(self, flag=_noarg_):1972"""Set or get the status for propagation of geometry information.19731974A boolean argument specifies whether the geometry information1975of the slaves will determine the size of this widget. If no argument1976is given, the current setting will be returned.1977"""1978if flag is Misc._noarg_:1979return self._getboolean(self.tk.call(1980'grid', 'propagate', self._w))1981else:1982self.tk.call('grid', 'propagate', self._w, flag)19831984def grid_rowconfigure(self, index, cnf={}, **kw):1985"""Configure row INDEX of a grid.19861987Valid resources are minsize (minimum size of the row),1988weight (how much does additional space propagate to this row)1989and pad (how much space to let additionally)."""1990return self._grid_configure('rowconfigure', index, cnf, kw)19911992rowconfigure = grid_rowconfigure19931994def grid_size(self):1995"""Return a tuple of the number of column and rows in the grid."""1996return self._getints(1997self.tk.call('grid', 'size', self._w)) or None19981999size = grid_size20002001def grid_slaves(self, row=None, column=None):2002"""Return a list of all slaves of this widget2003in its packing order."""2004args = ()2005if row is not None:2006args = args + ('-row', row)2007if column is not None:2008args = args + ('-column', column)2009return [self._nametowidget(x) for x in2010self.tk.splitlist(self.tk.call(2011('grid', 'slaves', self._w) + args))]20122013# Support for the "event" command, new in Tk 4.2.2014# By Case Roole.20152016def event_add(self, virtual, *sequences):2017"""Bind a virtual event VIRTUAL (of the form <<Name>>)2018to an event SEQUENCE such that the virtual event is triggered2019whenever SEQUENCE occurs."""2020args = ('event', 'add', virtual) + sequences2021self.tk.call(args)20222023def event_delete(self, virtual, *sequences):2024"""Unbind a virtual event VIRTUAL from SEQUENCE."""2025args = ('event', 'delete', virtual) + sequences2026self.tk.call(args)20272028def event_generate(self, sequence, **kw):2029"""Generate an event SEQUENCE. Additional2030keyword arguments specify parameter of the event2031(e.g. x, y, rootx, rooty)."""2032args = ('event', 'generate', self._w, sequence)2033for k, v in kw.items():2034args = args + ('-%s' % k, str(v))2035self.tk.call(args)20362037def event_info(self, virtual=None):2038"""Return a list of all virtual events or the information2039about the SEQUENCE bound to the virtual event VIRTUAL."""2040return self.tk.splitlist(2041self.tk.call('event', 'info', virtual))20422043# Image related commands20442045def image_names(self):2046"""Return a list of all existing image names."""2047return self.tk.splitlist(self.tk.call('image', 'names'))20482049def image_types(self):2050"""Return a list of all available image types (e.g. photo bitmap)."""2051return self.tk.splitlist(self.tk.call('image', 'types'))205220532054class CallWrapper:2055"""Internal class. Stores function to call when some user2056defined Tcl function is called e.g. after an event occurred."""20572058def __init__(self, func, subst, widget):2059"""Store FUNC, SUBST and WIDGET as members."""2060self.func = func2061self.subst = subst2062self.widget = widget20632064def __call__(self, *args):2065"""Apply first function SUBST to arguments, than FUNC."""2066try:2067if self.subst:2068args = self.subst(*args)2069return self.func(*args)2070except SystemExit:2071raise2072except:2073self.widget._report_exception()207420752076class XView:2077"""Mix-in class for querying and changing the horizontal position2078of a widget's window."""20792080def xview(self, *args):2081"""Query and change the horizontal position of the view."""2082res = self.tk.call(self._w, 'xview', *args)2083if not args:2084return self._getdoubles(res)20852086def xview_moveto(self, fraction):2087"""Adjusts the view in the window so that FRACTION of the2088total width of the canvas is off-screen to the left."""2089self.tk.call(self._w, 'xview', 'moveto', fraction)20902091def xview_scroll(self, number, what):2092"""Shift the x-view according to NUMBER which is measured in "units"2093or "pages" (WHAT)."""2094self.tk.call(self._w, 'xview', 'scroll', number, what)209520962097class YView:2098"""Mix-in class for querying and changing the vertical position2099of a widget's window."""21002101def yview(self, *args):2102"""Query and change the vertical position of the view."""2103res = self.tk.call(self._w, 'yview', *args)2104if not args:2105return self._getdoubles(res)21062107def yview_moveto(self, fraction):2108"""Adjusts the view in the window so that FRACTION of the2109total height of the canvas is off-screen to the top."""2110self.tk.call(self._w, 'yview', 'moveto', fraction)21112112def yview_scroll(self, number, what):2113"""Shift the y-view according to NUMBER which is measured in2114"units" or "pages" (WHAT)."""2115self.tk.call(self._w, 'yview', 'scroll', number, what)211621172118class Wm:2119"""Provides functions for the communication with the window manager."""21202121def wm_aspect(self,2122minNumer=None, minDenom=None,2123maxNumer=None, maxDenom=None):2124"""Instruct the window manager to set the aspect ratio (width/height)2125of this widget to be between MINNUMER/MINDENOM and MAXNUMER/MAXDENOM. Return a tuple2126of the actual values if no argument is given."""2127return self._getints(2128self.tk.call('wm', 'aspect', self._w,2129minNumer, minDenom,2130maxNumer, maxDenom))21312132aspect = wm_aspect21332134def wm_attributes(self, *args, return_python_dict=False, **kwargs):2135"""Return or sets platform specific attributes.21362137When called with a single argument return_python_dict=True,2138return a dict of the platform specific attributes and their values.2139When called without arguments or with a single argument2140return_python_dict=False, return a tuple containing intermixed2141attribute names with the minus prefix and their values.21422143When called with a single string value, return the value for the2144specific option. When called with keyword arguments, set the2145corresponding attributes.2146"""2147if not kwargs:2148if not args:2149res = self.tk.call('wm', 'attributes', self._w)2150if return_python_dict:2151return _splitdict(self.tk, res)2152else:2153return self.tk.splitlist(res)2154if len(args) == 1 and args[0] is not None:2155option = args[0]2156if option[0] == '-':2157# TODO: deprecate2158option = option[1:]2159return self.tk.call('wm', 'attributes', self._w, '-' + option)2160# TODO: deprecate2161return self.tk.call('wm', 'attributes', self._w, *args)2162elif args:2163raise TypeError('wm_attribute() options have been specified as '2164'positional and keyword arguments')2165else:2166self.tk.call('wm', 'attributes', self._w, *self._options(kwargs))21672168attributes = wm_attributes21692170def wm_client(self, name=None):2171"""Store NAME in WM_CLIENT_MACHINE property of this widget. Return2172current value."""2173return self.tk.call('wm', 'client', self._w, name)21742175client = wm_client21762177def wm_colormapwindows(self, *wlist):2178"""Store list of window names (WLIST) into WM_COLORMAPWINDOWS property2179of this widget. This list contains windows whose colormaps differ from their2180parents. Return current list of widgets if WLIST is empty."""2181if len(wlist) > 1:2182wlist = (wlist,) # Tk needs a list of windows here2183args = ('wm', 'colormapwindows', self._w) + wlist2184if wlist:2185self.tk.call(args)2186else:2187return [self._nametowidget(x)2188for x in self.tk.splitlist(self.tk.call(args))]21892190colormapwindows = wm_colormapwindows21912192def wm_command(self, value=None):2193"""Store VALUE in WM_COMMAND property. It is the command2194which shall be used to invoke the application. Return current2195command if VALUE is None."""2196return self.tk.call('wm', 'command', self._w, value)21972198command = wm_command21992200def wm_deiconify(self):2201"""Deiconify this widget. If it was never mapped it will not be mapped.2202On Windows it will raise this widget and give it the focus."""2203return self.tk.call('wm', 'deiconify', self._w)22042205deiconify = wm_deiconify22062207def wm_focusmodel(self, model=None):2208"""Set focus model to MODEL. "active" means that this widget will claim2209the focus itself, "passive" means that the window manager shall give2210the focus. Return current focus model if MODEL is None."""2211return self.tk.call('wm', 'focusmodel', self._w, model)22122213focusmodel = wm_focusmodel22142215def wm_forget(self, window): # new in Tk 8.52216"""The window will be unmapped from the screen and will no longer2217be managed by wm. toplevel windows will be treated like frame2218windows once they are no longer managed by wm, however, the menu2219option configuration will be remembered and the menus will return2220once the widget is managed again."""2221self.tk.call('wm', 'forget', window)22222223forget = wm_forget22242225def wm_frame(self):2226"""Return identifier for decorative frame of this widget if present."""2227return self.tk.call('wm', 'frame', self._w)22282229frame = wm_frame22302231def wm_geometry(self, newGeometry=None):2232"""Set geometry to NEWGEOMETRY of the form =widthxheight+x+y. Return2233current value if None is given."""2234return self.tk.call('wm', 'geometry', self._w, newGeometry)22352236geometry = wm_geometry22372238def wm_grid(self,2239baseWidth=None, baseHeight=None,2240widthInc=None, heightInc=None):2241"""Instruct the window manager that this widget shall only be2242resized on grid boundaries. WIDTHINC and HEIGHTINC are the width and2243height of a grid unit in pixels. BASEWIDTH and BASEHEIGHT are the2244number of grid units requested in Tk_GeometryRequest."""2245return self._getints(self.tk.call(2246'wm', 'grid', self._w,2247baseWidth, baseHeight, widthInc, heightInc))22482249grid = wm_grid22502251def wm_group(self, pathName=None):2252"""Set the group leader widgets for related widgets to PATHNAME. Return2253the group leader of this widget if None is given."""2254return self.tk.call('wm', 'group', self._w, pathName)22552256group = wm_group22572258def wm_iconbitmap(self, bitmap=None, default=None):2259"""Set bitmap for the iconified widget to BITMAP. Return2260the bitmap if None is given.22612262Under Windows, the DEFAULT parameter can be used to set the icon2263for the widget and any descendants that don't have an icon set2264explicitly. DEFAULT can be the relative path to a .ico file2265(example: root.iconbitmap(default='myicon.ico') ). See Tk2266documentation for more information."""2267if default:2268return self.tk.call('wm', 'iconbitmap', self._w, '-default', default)2269else:2270return self.tk.call('wm', 'iconbitmap', self._w, bitmap)22712272iconbitmap = wm_iconbitmap22732274def wm_iconify(self):2275"""Display widget as icon."""2276return self.tk.call('wm', 'iconify', self._w)22772278iconify = wm_iconify22792280def wm_iconmask(self, bitmap=None):2281"""Set mask for the icon bitmap of this widget. Return the2282mask if None is given."""2283return self.tk.call('wm', 'iconmask', self._w, bitmap)22842285iconmask = wm_iconmask22862287def wm_iconname(self, newName=None):2288"""Set the name of the icon for this widget. Return the name if2289None is given."""2290return self.tk.call('wm', 'iconname', self._w, newName)22912292iconname = wm_iconname22932294def wm_iconphoto(self, default=False, *args): # new in Tk 8.52295"""Sets the titlebar icon for this window based on the named photo2296images passed through args. If default is True, this is applied to2297all future created toplevels as well.22982299The data in the images is taken as a snapshot at the time of2300invocation. If the images are later changed, this is not reflected2301to the titlebar icons. Multiple images are accepted to allow2302different images sizes to be provided. The window manager may scale2303provided icons to an appropriate size.23042305On Windows, the images are packed into a Windows icon structure.2306This will override an icon specified to wm_iconbitmap, and vice2307versa.23082309On X, the images are arranged into the _NET_WM_ICON X property,2310which most modern window managers support. An icon specified by2311wm_iconbitmap may exist simultaneously.23122313On Macintosh, this currently does nothing."""2314if default:2315self.tk.call('wm', 'iconphoto', self._w, "-default", *args)2316else:2317self.tk.call('wm', 'iconphoto', self._w, *args)23182319iconphoto = wm_iconphoto23202321def wm_iconposition(self, x=None, y=None):2322"""Set the position of the icon of this widget to X and Y. Return2323a tuple of the current values of X and X if None is given."""2324return self._getints(self.tk.call(2325'wm', 'iconposition', self._w, x, y))23262327iconposition = wm_iconposition23282329def wm_iconwindow(self, pathName=None):2330"""Set widget PATHNAME to be displayed instead of icon. Return the current2331value if None is given."""2332return self.tk.call('wm', 'iconwindow', self._w, pathName)23332334iconwindow = wm_iconwindow23352336def wm_manage(self, widget): # new in Tk 8.52337"""The widget specified will become a stand alone top-level window.2338The window will be decorated with the window managers title bar,2339etc."""2340self.tk.call('wm', 'manage', widget)23412342manage = wm_manage23432344def wm_maxsize(self, width=None, height=None):2345"""Set max WIDTH and HEIGHT for this widget. If the window is gridded2346the values are given in grid units. Return the current values if None2347is given."""2348return self._getints(self.tk.call(2349'wm', 'maxsize', self._w, width, height))23502351maxsize = wm_maxsize23522353def wm_minsize(self, width=None, height=None):2354"""Set min WIDTH and HEIGHT for this widget. If the window is gridded2355the values are given in grid units. Return the current values if None2356is given."""2357return self._getints(self.tk.call(2358'wm', 'minsize', self._w, width, height))23592360minsize = wm_minsize23612362def wm_overrideredirect(self, boolean=None):2363"""Instruct the window manager to ignore this widget2364if BOOLEAN is given with 1. Return the current value if None2365is given."""2366return self._getboolean(self.tk.call(2367'wm', 'overrideredirect', self._w, boolean))23682369overrideredirect = wm_overrideredirect23702371def wm_positionfrom(self, who=None):2372"""Instruct the window manager that the position of this widget shall2373be defined by the user if WHO is "user", and by its own policy if WHO is2374"program"."""2375return self.tk.call('wm', 'positionfrom', self._w, who)23762377positionfrom = wm_positionfrom23782379def wm_protocol(self, name=None, func=None):2380"""Bind function FUNC to command NAME for this widget.2381Return the function bound to NAME if None is given. NAME could be2382e.g. "WM_SAVE_YOURSELF" or "WM_DELETE_WINDOW"."""2383if callable(func):2384command = self._register(func)2385else:2386command = func2387return self.tk.call(2388'wm', 'protocol', self._w, name, command)23892390protocol = wm_protocol23912392def wm_resizable(self, width=None, height=None):2393"""Instruct the window manager whether this width can be resized2394in WIDTH or HEIGHT. Both values are boolean values."""2395return self.tk.call('wm', 'resizable', self._w, width, height)23962397resizable = wm_resizable23982399def wm_sizefrom(self, who=None):2400"""Instruct the window manager that the size of this widget shall2401be defined by the user if WHO is "user", and by its own policy if WHO is2402"program"."""2403return self.tk.call('wm', 'sizefrom', self._w, who)24042405sizefrom = wm_sizefrom24062407def wm_state(self, newstate=None):2408"""Query or set the state of this widget as one of normal, icon,2409iconic (see wm_iconwindow), withdrawn, or zoomed (Windows only)."""2410return self.tk.call('wm', 'state', self._w, newstate)24112412state = wm_state24132414def wm_title(self, string=None):2415"""Set the title of this widget."""2416return self.tk.call('wm', 'title', self._w, string)24172418title = wm_title24192420def wm_transient(self, master=None):2421"""Instruct the window manager that this widget is transient2422with regard to widget MASTER."""2423return self.tk.call('wm', 'transient', self._w, master)24242425transient = wm_transient24262427def wm_withdraw(self):2428"""Withdraw this widget from the screen such that it is unmapped2429and forgotten by the window manager. Re-draw it with wm_deiconify."""2430return self.tk.call('wm', 'withdraw', self._w)24312432withdraw = wm_withdraw243324342435class Tk(Misc, Wm):2436"""Toplevel widget of Tk which represents mostly the main window2437of an application. It has an associated Tcl interpreter."""2438_w = '.'24392440def __init__(self, screenName=None, baseName=None, className='Tk',2441useTk=True, sync=False, use=None):2442"""Return a new top level widget on screen SCREENNAME. A new Tcl interpreter will2443be created. BASENAME will be used for the identification of the profile file (see2444readprofile).2445It is constructed from sys.argv[0] without extensions if None is given. CLASSNAME2446is the name of the widget class."""2447self.master = None2448self.children = {}2449self._tkloaded = False2450# to avoid recursions in the getattr code in case of failure, we2451# ensure that self.tk is always _something_.2452self.tk = None2453if baseName is None:2454import os2455baseName = os.path.basename(sys.argv[0])2456baseName, ext = os.path.splitext(baseName)2457if ext not in ('.py', '.pyc'):2458baseName = baseName + ext2459interactive = False2460self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)2461if _debug:2462self.tk.settrace(_print_command)2463if useTk:2464self._loadtk()2465if not sys.flags.ignore_environment:2466# Issue #16248: Honor the -E flag to avoid code injection.2467self.readprofile(baseName, className)24682469def loadtk(self):2470if not self._tkloaded:2471self.tk.loadtk()2472self._loadtk()24732474def _loadtk(self):2475self._tkloaded = True2476global _default_root2477# Version sanity checks2478tk_version = self.tk.getvar('tk_version')2479if tk_version != _tkinter.TK_VERSION:2480raise RuntimeError("tk.h version (%s) doesn't match libtk.a version (%s)"2481% (_tkinter.TK_VERSION, tk_version))2482# Under unknown circumstances, tcl_version gets coerced to float2483tcl_version = str(self.tk.getvar('tcl_version'))2484if tcl_version != _tkinter.TCL_VERSION:2485raise RuntimeError("tcl.h version (%s) doesn't match libtcl.a version (%s)" \2486% (_tkinter.TCL_VERSION, tcl_version))2487# Create and register the tkerror and exit commands2488# We need to inline parts of _register here, _ register2489# would register differently-named commands.2490if self._tclCommands is None:2491self._tclCommands = []2492self.tk.createcommand('tkerror', _tkerror)2493self.tk.createcommand('exit', _exit)2494self._tclCommands.append('tkerror')2495self._tclCommands.append('exit')2496if _support_default_root and _default_root is None:2497_default_root = self2498self.protocol("WM_DELETE_WINDOW", self.destroy)24992500def destroy(self):2501"""Destroy this and all descendants widgets. This will2502end the application of this Tcl interpreter."""2503for c in list(self.children.values()): c.destroy()2504self.tk.call('destroy', self._w)2505Misc.destroy(self)2506global _default_root2507if _support_default_root and _default_root is self:2508_default_root = None25092510def readprofile(self, baseName, className):2511"""Internal function. It reads .BASENAME.tcl and .CLASSNAME.tcl into2512the Tcl Interpreter and calls exec on the contents of .BASENAME.py and2513.CLASSNAME.py if such a file exists in the home directory."""2514import os2515if 'HOME' in os.environ: home = os.environ['HOME']2516else: home = os.curdir2517class_tcl = os.path.join(home, '.%s.tcl' % className)2518class_py = os.path.join(home, '.%s.py' % className)2519base_tcl = os.path.join(home, '.%s.tcl' % baseName)2520base_py = os.path.join(home, '.%s.py' % baseName)2521dir = {'self': self}2522exec('from tkinter import *', dir)2523if os.path.isfile(class_tcl):2524self.tk.call('source', class_tcl)2525if os.path.isfile(class_py):2526exec(open(class_py).read(), dir)2527if os.path.isfile(base_tcl):2528self.tk.call('source', base_tcl)2529if os.path.isfile(base_py):2530exec(open(base_py).read(), dir)25312532def report_callback_exception(self, exc, val, tb):2533"""Report callback exception on sys.stderr.25342535Applications may want to override this internal function, and2536should when sys.stderr is None."""2537import traceback2538print("Exception in Tkinter callback", file=sys.stderr)2539sys.last_exc = val2540sys.last_type = exc2541sys.last_value = val2542sys.last_traceback = tb2543traceback.print_exception(exc, val, tb)25442545def __getattr__(self, attr):2546"Delegate attribute access to the interpreter object"2547return getattr(self.tk, attr)254825492550def _print_command(cmd, *, file=sys.stderr):2551# Print executed Tcl/Tk commands.2552assert isinstance(cmd, tuple)2553cmd = _join(cmd)2554print(cmd, file=file)255525562557# Ideally, the classes Pack, Place and Grid disappear, the2558# pack/place/grid methods are defined on the Widget class, and2559# everybody uses w.pack_whatever(...) instead of Pack.whatever(w,2560# ...), with pack(), place() and grid() being short for2561# pack_configure(), place_configure() and grid_columnconfigure(), and2562# forget() being short for pack_forget(). As a practical matter, I'm2563# afraid that there is too much code out there that may be using the2564# Pack, Place or Grid class, so I leave them intact -- but only as2565# backwards compatibility features. Also note that those methods that2566# take a master as argument (e.g. pack_propagate) have been moved to2567# the Misc class (which now incorporates all methods common between2568# toplevel and interior widgets). Again, for compatibility, these are2569# copied into the Pack, Place or Grid class.257025712572def Tcl(screenName=None, baseName=None, className='Tk', useTk=False):2573return Tk(screenName, baseName, className, useTk)257425752576class Pack:2577"""Geometry manager Pack.25782579Base class to use the methods pack_* in every widget."""25802581def pack_configure(self, cnf={}, **kw):2582"""Pack a widget in the parent widget. Use as options:2583after=widget - pack it after you have packed widget2584anchor=NSEW (or subset) - position widget according to2585given direction2586before=widget - pack it before you will pack widget2587expand=bool - expand widget if parent size grows2588fill=NONE or X or Y or BOTH - fill widget if widget grows2589in=master - use master to contain this widget2590in_=master - see 'in' option description2591ipadx=amount - add internal padding in x direction2592ipady=amount - add internal padding in y direction2593padx=amount - add padding in x direction2594pady=amount - add padding in y direction2595side=TOP or BOTTOM or LEFT or RIGHT - where to add this widget.2596"""2597self.tk.call(2598('pack', 'configure', self._w)2599+ self._options(cnf, kw))26002601pack = configure = config = pack_configure26022603def pack_forget(self):2604"""Unmap this widget and do not use it for the packing order."""2605self.tk.call('pack', 'forget', self._w)26062607forget = pack_forget26082609def pack_info(self):2610"""Return information about the packing options2611for this widget."""2612d = _splitdict(self.tk, self.tk.call('pack', 'info', self._w))2613if 'in' in d:2614d['in'] = self.nametowidget(d['in'])2615return d26162617info = pack_info2618propagate = pack_propagate = Misc.pack_propagate2619slaves = pack_slaves = Misc.pack_slaves262026212622class Place:2623"""Geometry manager Place.26242625Base class to use the methods place_* in every widget."""26262627def place_configure(self, cnf={}, **kw):2628"""Place a widget in the parent widget. Use as options:2629in=master - master relative to which the widget is placed2630in_=master - see 'in' option description2631x=amount - locate anchor of this widget at position x of master2632y=amount - locate anchor of this widget at position y of master2633relx=amount - locate anchor of this widget between 0.0 and 1.02634relative to width of master (1.0 is right edge)2635rely=amount - locate anchor of this widget between 0.0 and 1.02636relative to height of master (1.0 is bottom edge)2637anchor=NSEW (or subset) - position anchor according to given direction2638width=amount - width of this widget in pixel2639height=amount - height of this widget in pixel2640relwidth=amount - width of this widget between 0.0 and 1.02641relative to width of master (1.0 is the same width2642as the master)2643relheight=amount - height of this widget between 0.0 and 1.02644relative to height of master (1.0 is the same2645height as the master)2646bordermode="inside" or "outside" - whether to take border width of2647master widget into account2648"""2649self.tk.call(2650('place', 'configure', self._w)2651+ self._options(cnf, kw))26522653place = configure = config = place_configure26542655def place_forget(self):2656"""Unmap this widget."""2657self.tk.call('place', 'forget', self._w)26582659forget = place_forget26602661def place_info(self):2662"""Return information about the placing options2663for this widget."""2664d = _splitdict(self.tk, self.tk.call('place', 'info', self._w))2665if 'in' in d:2666d['in'] = self.nametowidget(d['in'])2667return d26682669info = place_info2670slaves = place_slaves = Misc.place_slaves267126722673class Grid:2674"""Geometry manager Grid.26752676Base class to use the methods grid_* in every widget."""2677# Thanks to Masazumi Yoshikawa ([email protected])26782679def grid_configure(self, cnf={}, **kw):2680"""Position a widget in the parent widget in a grid. Use as options:2681column=number - use cell identified with given column (starting with 0)2682columnspan=number - this widget will span several columns2683in=master - use master to contain this widget2684in_=master - see 'in' option description2685ipadx=amount - add internal padding in x direction2686ipady=amount - add internal padding in y direction2687padx=amount - add padding in x direction2688pady=amount - add padding in y direction2689row=number - use cell identified with given row (starting with 0)2690rowspan=number - this widget will span several rows2691sticky=NSEW - if cell is larger on which sides will this2692widget stick to the cell boundary2693"""2694self.tk.call(2695('grid', 'configure', self._w)2696+ self._options(cnf, kw))26972698grid = configure = config = grid_configure2699bbox = grid_bbox = Misc.grid_bbox2700columnconfigure = grid_columnconfigure = Misc.grid_columnconfigure27012702def grid_forget(self):2703"""Unmap this widget."""2704self.tk.call('grid', 'forget', self._w)27052706forget = grid_forget27072708def grid_remove(self):2709"""Unmap this widget but remember the grid options."""2710self.tk.call('grid', 'remove', self._w)27112712def grid_info(self):2713"""Return information about the options2714for positioning this widget in a grid."""2715d = _splitdict(self.tk, self.tk.call('grid', 'info', self._w))2716if 'in' in d:2717d['in'] = self.nametowidget(d['in'])2718return d27192720info = grid_info2721location = grid_location = Misc.grid_location2722propagate = grid_propagate = Misc.grid_propagate2723rowconfigure = grid_rowconfigure = Misc.grid_rowconfigure2724size = grid_size = Misc.grid_size2725slaves = grid_slaves = Misc.grid_slaves272627272728class BaseWidget(Misc):2729"""Internal class."""27302731def _setup(self, master, cnf):2732"""Internal function. Sets up information about children."""2733if master is None:2734master = _get_default_root()2735self.master = master2736self.tk = master.tk2737name = None2738if 'name' in cnf:2739name = cnf['name']2740del cnf['name']2741if not name:2742name = self.__class__.__name__.lower()2743if master._last_child_ids is None:2744master._last_child_ids = {}2745count = master._last_child_ids.get(name, 0) + 12746master._last_child_ids[name] = count2747if count == 1:2748name = '!%s' % (name,)2749else:2750name = '!%s%d' % (name, count)2751self._name = name2752if master._w=='.':2753self._w = '.' + name2754else:2755self._w = master._w + '.' + name2756self.children = {}2757if self._name in self.master.children:2758self.master.children[self._name].destroy()2759self.master.children[self._name] = self27602761def __init__(self, master, widgetName, cnf={}, kw={}, extra=()):2762"""Construct a widget with the parent widget MASTER, a name WIDGETNAME2763and appropriate options."""2764if kw:2765cnf = _cnfmerge((cnf, kw))2766self.widgetName = widgetName2767self._setup(master, cnf)2768if self._tclCommands is None:2769self._tclCommands = []2770classes = [(k, v) for k, v in cnf.items() if isinstance(k, type)]2771for k, v in classes:2772del cnf[k]2773self.tk.call(2774(widgetName, self._w) + extra + self._options(cnf))2775for k, v in classes:2776k.configure(self, v)27772778def destroy(self):2779"""Destroy this and all descendants widgets."""2780for c in list(self.children.values()): c.destroy()2781self.tk.call('destroy', self._w)2782if self._name in self.master.children:2783del self.master.children[self._name]2784Misc.destroy(self)27852786def _do(self, name, args=()):2787# XXX Obsolete -- better use self.tk.call directly!2788return self.tk.call((self._w, name) + args)278927902791class Widget(BaseWidget, Pack, Place, Grid):2792"""Internal class.27932794Base class for a widget which can be positioned with the geometry managers2795Pack, Place or Grid."""2796pass279727982799class Toplevel(BaseWidget, Wm):2800"""Toplevel widget, e.g. for dialogs."""28012802def __init__(self, master=None, cnf={}, **kw):2803"""Construct a toplevel widget with the parent MASTER.28042805Valid resource names: background, bd, bg, borderwidth, class,2806colormap, container, cursor, height, highlightbackground,2807highlightcolor, highlightthickness, menu, relief, screen, takefocus,2808use, visual, width."""2809if kw:2810cnf = _cnfmerge((cnf, kw))2811extra = ()2812for wmkey in ['screen', 'class_', 'class', 'visual',2813'colormap']:2814if wmkey in cnf:2815val = cnf[wmkey]2816# TBD: a hack needed because some keys2817# are not valid as keyword arguments2818if wmkey[-1] == '_': opt = '-'+wmkey[:-1]2819else: opt = '-'+wmkey2820extra = extra + (opt, val)2821del cnf[wmkey]2822BaseWidget.__init__(self, master, 'toplevel', cnf, {}, extra)2823root = self._root()2824self.iconname(root.iconname())2825self.title(root.title())2826self.protocol("WM_DELETE_WINDOW", self.destroy)282728282829class Button(Widget):2830"""Button widget."""28312832def __init__(self, master=None, cnf={}, **kw):2833"""Construct a button widget with the parent MASTER.28342835STANDARD OPTIONS28362837activebackground, activeforeground, anchor,2838background, bitmap, borderwidth, cursor,2839disabledforeground, font, foreground2840highlightbackground, highlightcolor,2841highlightthickness, image, justify,2842padx, pady, relief, repeatdelay,2843repeatinterval, takefocus, text,2844textvariable, underline, wraplength28452846WIDGET-SPECIFIC OPTIONS28472848command, compound, default, height,2849overrelief, state, width2850"""2851Widget.__init__(self, master, 'button', cnf, kw)28522853def flash(self):2854"""Flash the button.28552856This is accomplished by redisplaying2857the button several times, alternating between active and2858normal colors. At the end of the flash the button is left2859in the same normal/active state as when the command was2860invoked. This command is ignored if the button's state is2861disabled.2862"""2863self.tk.call(self._w, 'flash')28642865def invoke(self):2866"""Invoke the command associated with the button.28672868The return value is the return value from the command,2869or an empty string if there is no command associated with2870the button. This command is ignored if the button's state2871is disabled.2872"""2873return self.tk.call(self._w, 'invoke')287428752876class Canvas(Widget, XView, YView):2877"""Canvas widget to display graphical elements like lines or text."""28782879def __init__(self, master=None, cnf={}, **kw):2880"""Construct a canvas widget with the parent MASTER.28812882Valid resource names: background, bd, bg, borderwidth, closeenough,2883confine, cursor, height, highlightbackground, highlightcolor,2884highlightthickness, insertbackground, insertborderwidth,2885insertofftime, insertontime, insertwidth, offset, relief,2886scrollregion, selectbackground, selectborderwidth, selectforeground,2887state, takefocus, width, xscrollcommand, xscrollincrement,2888yscrollcommand, yscrollincrement."""2889Widget.__init__(self, master, 'canvas', cnf, kw)28902891def addtag(self, *args):2892"""Internal function."""2893self.tk.call((self._w, 'addtag') + args)28942895def addtag_above(self, newtag, tagOrId):2896"""Add tag NEWTAG to all items above TAGORID."""2897self.addtag(newtag, 'above', tagOrId)28982899def addtag_all(self, newtag):2900"""Add tag NEWTAG to all items."""2901self.addtag(newtag, 'all')29022903def addtag_below(self, newtag, tagOrId):2904"""Add tag NEWTAG to all items below TAGORID."""2905self.addtag(newtag, 'below', tagOrId)29062907def addtag_closest(self, newtag, x, y, halo=None, start=None):2908"""Add tag NEWTAG to item which is closest to pixel at X, Y.2909If several match take the top-most.2910All items closer than HALO are considered overlapping (all are2911closest). If START is specified the next below this tag is taken."""2912self.addtag(newtag, 'closest', x, y, halo, start)29132914def addtag_enclosed(self, newtag, x1, y1, x2, y2):2915"""Add tag NEWTAG to all items in the rectangle defined2916by X1,Y1,X2,Y2."""2917self.addtag(newtag, 'enclosed', x1, y1, x2, y2)29182919def addtag_overlapping(self, newtag, x1, y1, x2, y2):2920"""Add tag NEWTAG to all items which overlap the rectangle2921defined by X1,Y1,X2,Y2."""2922self.addtag(newtag, 'overlapping', x1, y1, x2, y2)29232924def addtag_withtag(self, newtag, tagOrId):2925"""Add tag NEWTAG to all items with TAGORID."""2926self.addtag(newtag, 'withtag', tagOrId)29272928def bbox(self, *args):2929"""Return a tuple of X1,Y1,X2,Y2 coordinates for a rectangle2930which encloses all items with tags specified as arguments."""2931return self._getints(2932self.tk.call((self._w, 'bbox') + args)) or None29332934def tag_unbind(self, tagOrId, sequence, funcid=None):2935"""Unbind for all items with TAGORID for event SEQUENCE the2936function identified with FUNCID."""2937self._unbind((self._w, 'bind', tagOrId, sequence), funcid)29382939def tag_bind(self, tagOrId, sequence=None, func=None, add=None):2940"""Bind to all items with TAGORID at event SEQUENCE a call to function FUNC.29412942An additional boolean parameter ADD specifies whether FUNC will be2943called additionally to the other bound function or whether it will2944replace the previous function. See bind for the return value."""2945return self._bind((self._w, 'bind', tagOrId),2946sequence, func, add)29472948def canvasx(self, screenx, gridspacing=None):2949"""Return the canvas x coordinate of pixel position SCREENX rounded2950to nearest multiple of GRIDSPACING units."""2951return self.tk.getdouble(self.tk.call(2952self._w, 'canvasx', screenx, gridspacing))29532954def canvasy(self, screeny, gridspacing=None):2955"""Return the canvas y coordinate of pixel position SCREENY rounded2956to nearest multiple of GRIDSPACING units."""2957return self.tk.getdouble(self.tk.call(2958self._w, 'canvasy', screeny, gridspacing))29592960def coords(self, *args):2961"""Return a list of coordinates for the item given in ARGS."""2962args = _flatten(args)2963return [self.tk.getdouble(x) for x in2964self.tk.splitlist(2965self.tk.call((self._w, 'coords') + args))]29662967def _create(self, itemType, args, kw): # Args: (val, val, ..., cnf={})2968"""Internal function."""2969args = _flatten(args)2970cnf = args[-1]2971if isinstance(cnf, (dict, tuple)):2972args = args[:-1]2973else:2974cnf = {}2975return self.tk.getint(self.tk.call(2976self._w, 'create', itemType,2977*(args + self._options(cnf, kw))))29782979def create_arc(self, *args, **kw):2980"""Create arc shaped region with coordinates x1,y1,x2,y2."""2981return self._create('arc', args, kw)29822983def create_bitmap(self, *args, **kw):2984"""Create bitmap with coordinates x1,y1."""2985return self._create('bitmap', args, kw)29862987def create_image(self, *args, **kw):2988"""Create image item with coordinates x1,y1."""2989return self._create('image', args, kw)29902991def create_line(self, *args, **kw):2992"""Create line with coordinates x1,y1,...,xn,yn."""2993return self._create('line', args, kw)29942995def create_oval(self, *args, **kw):2996"""Create oval with coordinates x1,y1,x2,y2."""2997return self._create('oval', args, kw)29982999def create_polygon(self, *args, **kw):3000"""Create polygon with coordinates x1,y1,...,xn,yn."""3001return self._create('polygon', args, kw)30023003def create_rectangle(self, *args, **kw):3004"""Create rectangle with coordinates x1,y1,x2,y2."""3005return self._create('rectangle', args, kw)30063007def create_text(self, *args, **kw):3008"""Create text with coordinates x1,y1."""3009return self._create('text', args, kw)30103011def create_window(self, *args, **kw):3012"""Create window with coordinates x1,y1,x2,y2."""3013return self._create('window', args, kw)30143015def dchars(self, *args):3016"""Delete characters of text items identified by tag or id in ARGS (possibly3017several times) from FIRST to LAST character (including)."""3018self.tk.call((self._w, 'dchars') + args)30193020def delete(self, *args):3021"""Delete items identified by all tag or ids contained in ARGS."""3022self.tk.call((self._w, 'delete') + args)30233024def dtag(self, *args):3025"""Delete tag or id given as last arguments in ARGS from items3026identified by first argument in ARGS."""3027self.tk.call((self._w, 'dtag') + args)30283029def find(self, *args):3030"""Internal function."""3031return self._getints(3032self.tk.call((self._w, 'find') + args)) or ()30333034def find_above(self, tagOrId):3035"""Return items above TAGORID."""3036return self.find('above', tagOrId)30373038def find_all(self):3039"""Return all items."""3040return self.find('all')30413042def find_below(self, tagOrId):3043"""Return all items below TAGORID."""3044return self.find('below', tagOrId)30453046def find_closest(self, x, y, halo=None, start=None):3047"""Return item which is closest to pixel at X, Y.3048If several match take the top-most.3049All items closer than HALO are considered overlapping (all are3050closest). If START is specified the next below this tag is taken."""3051return self.find('closest', x, y, halo, start)30523053def find_enclosed(self, x1, y1, x2, y2):3054"""Return all items in rectangle defined3055by X1,Y1,X2,Y2."""3056return self.find('enclosed', x1, y1, x2, y2)30573058def find_overlapping(self, x1, y1, x2, y2):3059"""Return all items which overlap the rectangle3060defined by X1,Y1,X2,Y2."""3061return self.find('overlapping', x1, y1, x2, y2)30623063def find_withtag(self, tagOrId):3064"""Return all items with TAGORID."""3065return self.find('withtag', tagOrId)30663067def focus(self, *args):3068"""Set focus to the first item specified in ARGS."""3069return self.tk.call((self._w, 'focus') + args)30703071def gettags(self, *args):3072"""Return tags associated with the first item specified in ARGS."""3073return self.tk.splitlist(3074self.tk.call((self._w, 'gettags') + args))30753076def icursor(self, *args):3077"""Set cursor at position POS in the item identified by TAGORID.3078In ARGS TAGORID must be first."""3079self.tk.call((self._w, 'icursor') + args)30803081def index(self, *args):3082"""Return position of cursor as integer in item specified in ARGS."""3083return self.tk.getint(self.tk.call((self._w, 'index') + args))30843085def insert(self, *args):3086"""Insert TEXT in item TAGORID at position POS. ARGS must3087be TAGORID POS TEXT."""3088self.tk.call((self._w, 'insert') + args)30893090def itemcget(self, tagOrId, option):3091"""Return the resource value for an OPTION for item TAGORID."""3092return self.tk.call(3093(self._w, 'itemcget') + (tagOrId, '-'+option))30943095def itemconfigure(self, tagOrId, cnf=None, **kw):3096"""Configure resources of an item TAGORID.30973098The values for resources are specified as keyword3099arguments. To get an overview about3100the allowed keyword arguments call the method without arguments.3101"""3102return self._configure(('itemconfigure', tagOrId), cnf, kw)31033104itemconfig = itemconfigure31053106# lower, tkraise/lift hide Misc.lower, Misc.tkraise/lift,3107# so the preferred name for them is tag_lower, tag_raise3108# (similar to tag_bind, and similar to the Text widget);3109# unfortunately can't delete the old ones yet (maybe in 1.6)3110def tag_lower(self, *args):3111"""Lower an item TAGORID given in ARGS3112(optional below another item)."""3113self.tk.call((self._w, 'lower') + args)31143115lower = tag_lower31163117def move(self, *args):3118"""Move an item TAGORID given in ARGS."""3119self.tk.call((self._w, 'move') + args)31203121def moveto(self, tagOrId, x='', y=''):3122"""Move the items given by TAGORID in the canvas coordinate3123space so that the first coordinate pair of the bottommost3124item with tag TAGORID is located at position (X,Y).3125X and Y may be the empty string, in which case the3126corresponding coordinate will be unchanged. All items matching3127TAGORID remain in the same positions relative to each other."""3128self.tk.call(self._w, 'moveto', tagOrId, x, y)31293130def postscript(self, cnf={}, **kw):3131"""Print the contents of the canvas to a postscript3132file. Valid options: colormap, colormode, file, fontmap,3133height, pageanchor, pageheight, pagewidth, pagex, pagey,3134rotate, width, x, y."""3135return self.tk.call((self._w, 'postscript') +3136self._options(cnf, kw))31373138def tag_raise(self, *args):3139"""Raise an item TAGORID given in ARGS3140(optional above another item)."""3141self.tk.call((self._w, 'raise') + args)31423143lift = tkraise = tag_raise31443145def scale(self, *args):3146"""Scale item TAGORID with XORIGIN, YORIGIN, XSCALE, YSCALE."""3147self.tk.call((self._w, 'scale') + args)31483149def scan_mark(self, x, y):3150"""Remember the current X, Y coordinates."""3151self.tk.call(self._w, 'scan', 'mark', x, y)31523153def scan_dragto(self, x, y, gain=10):3154"""Adjust the view of the canvas to GAIN times the3155difference between X and Y and the coordinates given in3156scan_mark."""3157self.tk.call(self._w, 'scan', 'dragto', x, y, gain)31583159def select_adjust(self, tagOrId, index):3160"""Adjust the end of the selection near the cursor of an item TAGORID to index."""3161self.tk.call(self._w, 'select', 'adjust', tagOrId, index)31623163def select_clear(self):3164"""Clear the selection if it is in this widget."""3165self.tk.call(self._w, 'select', 'clear')31663167def select_from(self, tagOrId, index):3168"""Set the fixed end of a selection in item TAGORID to INDEX."""3169self.tk.call(self._w, 'select', 'from', tagOrId, index)31703171def select_item(self):3172"""Return the item which has the selection."""3173return self.tk.call(self._w, 'select', 'item') or None31743175def select_to(self, tagOrId, index):3176"""Set the variable end of a selection in item TAGORID to INDEX."""3177self.tk.call(self._w, 'select', 'to', tagOrId, index)31783179def type(self, tagOrId):3180"""Return the type of the item TAGORID."""3181return self.tk.call(self._w, 'type', tagOrId) or None318231833184_checkbutton_count = 031853186class Checkbutton(Widget):3187"""Checkbutton widget which is either in on- or off-state."""31883189def __init__(self, master=None, cnf={}, **kw):3190"""Construct a checkbutton widget with the parent MASTER.31913192Valid resource names: activebackground, activeforeground, anchor,3193background, bd, bg, bitmap, borderwidth, command, cursor,3194disabledforeground, fg, font, foreground, height,3195highlightbackground, highlightcolor, highlightthickness, image,3196indicatoron, justify, offvalue, onvalue, padx, pady, relief,3197selectcolor, selectimage, state, takefocus, text, textvariable,3198underline, variable, width, wraplength."""3199Widget.__init__(self, master, 'checkbutton', cnf, kw)32003201def _setup(self, master, cnf):3202# Because Checkbutton defaults to a variable with the same name as3203# the widget, Checkbutton default names must be globally unique,3204# not just unique within the parent widget.3205if not cnf.get('name'):3206global _checkbutton_count3207name = self.__class__.__name__.lower()3208_checkbutton_count += 13209# To avoid collisions with ttk.Checkbutton, use the different3210# name template.3211cnf['name'] = f'!{name}-{_checkbutton_count}'3212super()._setup(master, cnf)32133214def deselect(self):3215"""Put the button in off-state."""3216self.tk.call(self._w, 'deselect')32173218def flash(self):3219"""Flash the button."""3220self.tk.call(self._w, 'flash')32213222def invoke(self):3223"""Toggle the button and invoke a command if given as resource."""3224return self.tk.call(self._w, 'invoke')32253226def select(self):3227"""Put the button in on-state."""3228self.tk.call(self._w, 'select')32293230def toggle(self):3231"""Toggle the button."""3232self.tk.call(self._w, 'toggle')323332343235class Entry(Widget, XView):3236"""Entry widget which allows displaying simple text."""32373238def __init__(self, master=None, cnf={}, **kw):3239"""Construct an entry widget with the parent MASTER.32403241Valid resource names: background, bd, bg, borderwidth, cursor,3242exportselection, fg, font, foreground, highlightbackground,3243highlightcolor, highlightthickness, insertbackground,3244insertborderwidth, insertofftime, insertontime, insertwidth,3245invalidcommand, invcmd, justify, relief, selectbackground,3246selectborderwidth, selectforeground, show, state, takefocus,3247textvariable, validate, validatecommand, vcmd, width,3248xscrollcommand."""3249Widget.__init__(self, master, 'entry', cnf, kw)32503251def delete(self, first, last=None):3252"""Delete text from FIRST to LAST (not included)."""3253self.tk.call(self._w, 'delete', first, last)32543255def get(self):3256"""Return the text."""3257return self.tk.call(self._w, 'get')32583259def icursor(self, index):3260"""Insert cursor at INDEX."""3261self.tk.call(self._w, 'icursor', index)32623263def index(self, index):3264"""Return position of cursor."""3265return self.tk.getint(self.tk.call(3266self._w, 'index', index))32673268def insert(self, index, string):3269"""Insert STRING at INDEX."""3270self.tk.call(self._w, 'insert', index, string)32713272def scan_mark(self, x):3273"""Remember the current X, Y coordinates."""3274self.tk.call(self._w, 'scan', 'mark', x)32753276def scan_dragto(self, x):3277"""Adjust the view of the canvas to 10 times the3278difference between X and Y and the coordinates given in3279scan_mark."""3280self.tk.call(self._w, 'scan', 'dragto', x)32813282def selection_adjust(self, index):3283"""Adjust the end of the selection near the cursor to INDEX."""3284self.tk.call(self._w, 'selection', 'adjust', index)32853286select_adjust = selection_adjust32873288def selection_clear(self):3289"""Clear the selection if it is in this widget."""3290self.tk.call(self._w, 'selection', 'clear')32913292select_clear = selection_clear32933294def selection_from(self, index):3295"""Set the fixed end of a selection to INDEX."""3296self.tk.call(self._w, 'selection', 'from', index)32973298select_from = selection_from32993300def selection_present(self):3301"""Return True if there are characters selected in the entry, False3302otherwise."""3303return self.tk.getboolean(3304self.tk.call(self._w, 'selection', 'present'))33053306select_present = selection_present33073308def selection_range(self, start, end):3309"""Set the selection from START to END (not included)."""3310self.tk.call(self._w, 'selection', 'range', start, end)33113312select_range = selection_range33133314def selection_to(self, index):3315"""Set the variable end of a selection to INDEX."""3316self.tk.call(self._w, 'selection', 'to', index)33173318select_to = selection_to331933203321class Frame(Widget):3322"""Frame widget which may contain other widgets and can have a 3D border."""33233324def __init__(self, master=None, cnf={}, **kw):3325"""Construct a frame widget with the parent MASTER.33263327Valid resource names: background, bd, bg, borderwidth, class,3328colormap, container, cursor, height, highlightbackground,3329highlightcolor, highlightthickness, relief, takefocus, visual, width."""3330cnf = _cnfmerge((cnf, kw))3331extra = ()3332if 'class_' in cnf:3333extra = ('-class', cnf['class_'])3334del cnf['class_']3335elif 'class' in cnf:3336extra = ('-class', cnf['class'])3337del cnf['class']3338Widget.__init__(self, master, 'frame', cnf, {}, extra)333933403341class Label(Widget):3342"""Label widget which can display text and bitmaps."""33433344def __init__(self, master=None, cnf={}, **kw):3345"""Construct a label widget with the parent MASTER.33463347STANDARD OPTIONS33483349activebackground, activeforeground, anchor,3350background, bitmap, borderwidth, cursor,3351disabledforeground, font, foreground,3352highlightbackground, highlightcolor,3353highlightthickness, image, justify,3354padx, pady, relief, takefocus, text,3355textvariable, underline, wraplength33563357WIDGET-SPECIFIC OPTIONS33583359height, state, width33603361"""3362Widget.__init__(self, master, 'label', cnf, kw)336333643365class Listbox(Widget, XView, YView):3366"""Listbox widget which can display a list of strings."""33673368def __init__(self, master=None, cnf={}, **kw):3369"""Construct a listbox widget with the parent MASTER.33703371Valid resource names: background, bd, bg, borderwidth, cursor,3372exportselection, fg, font, foreground, height, highlightbackground,3373highlightcolor, highlightthickness, relief, selectbackground,3374selectborderwidth, selectforeground, selectmode, setgrid, takefocus,3375width, xscrollcommand, yscrollcommand, listvariable."""3376Widget.__init__(self, master, 'listbox', cnf, kw)33773378def activate(self, index):3379"""Activate item identified by INDEX."""3380self.tk.call(self._w, 'activate', index)33813382def bbox(self, index):3383"""Return a tuple of X1,Y1,X2,Y2 coordinates for a rectangle3384which encloses the item identified by the given index."""3385return self._getints(self.tk.call(self._w, 'bbox', index)) or None33863387def curselection(self):3388"""Return the indices of currently selected item."""3389return self._getints(self.tk.call(self._w, 'curselection')) or ()33903391def delete(self, first, last=None):3392"""Delete items from FIRST to LAST (included)."""3393self.tk.call(self._w, 'delete', first, last)33943395def get(self, first, last=None):3396"""Get list of items from FIRST to LAST (included)."""3397if last is not None:3398return self.tk.splitlist(self.tk.call(3399self._w, 'get', first, last))3400else:3401return self.tk.call(self._w, 'get', first)34023403def index(self, index):3404"""Return index of item identified with INDEX."""3405i = self.tk.call(self._w, 'index', index)3406if i == 'none': return None3407return self.tk.getint(i)34083409def insert(self, index, *elements):3410"""Insert ELEMENTS at INDEX."""3411self.tk.call((self._w, 'insert', index) + elements)34123413def nearest(self, y):3414"""Get index of item which is nearest to y coordinate Y."""3415return self.tk.getint(self.tk.call(3416self._w, 'nearest', y))34173418def scan_mark(self, x, y):3419"""Remember the current X, Y coordinates."""3420self.tk.call(self._w, 'scan', 'mark', x, y)34213422def scan_dragto(self, x, y):3423"""Adjust the view of the listbox to 10 times the3424difference between X and Y and the coordinates given in3425scan_mark."""3426self.tk.call(self._w, 'scan', 'dragto', x, y)34273428def see(self, index):3429"""Scroll such that INDEX is visible."""3430self.tk.call(self._w, 'see', index)34313432def selection_anchor(self, index):3433"""Set the fixed end oft the selection to INDEX."""3434self.tk.call(self._w, 'selection', 'anchor', index)34353436select_anchor = selection_anchor34373438def selection_clear(self, first, last=None):3439"""Clear the selection from FIRST to LAST (included)."""3440self.tk.call(self._w,3441'selection', 'clear', first, last)34423443select_clear = selection_clear34443445def selection_includes(self, index):3446"""Return True if INDEX is part of the selection."""3447return self.tk.getboolean(self.tk.call(3448self._w, 'selection', 'includes', index))34493450select_includes = selection_includes34513452def selection_set(self, first, last=None):3453"""Set the selection from FIRST to LAST (included) without3454changing the currently selected elements."""3455self.tk.call(self._w, 'selection', 'set', first, last)34563457select_set = selection_set34583459def size(self):3460"""Return the number of elements in the listbox."""3461return self.tk.getint(self.tk.call(self._w, 'size'))34623463def itemcget(self, index, option):3464"""Return the resource value for an ITEM and an OPTION."""3465return self.tk.call(3466(self._w, 'itemcget') + (index, '-'+option))34673468def itemconfigure(self, index, cnf=None, **kw):3469"""Configure resources of an ITEM.34703471The values for resources are specified as keyword arguments.3472To get an overview about the allowed keyword arguments3473call the method without arguments.3474Valid resource names: background, bg, foreground, fg,3475selectbackground, selectforeground."""3476return self._configure(('itemconfigure', index), cnf, kw)34773478itemconfig = itemconfigure347934803481class Menu(Widget):3482"""Menu widget which allows displaying menu bars, pull-down menus and pop-up menus."""34833484def __init__(self, master=None, cnf={}, **kw):3485"""Construct menu widget with the parent MASTER.34863487Valid resource names: activebackground, activeborderwidth,3488activeforeground, background, bd, bg, borderwidth, cursor,3489disabledforeground, fg, font, foreground, postcommand, relief,3490selectcolor, takefocus, tearoff, tearoffcommand, title, type."""3491Widget.__init__(self, master, 'menu', cnf, kw)34923493def tk_popup(self, x, y, entry=""):3494"""Post the menu at position X,Y with entry ENTRY."""3495self.tk.call('tk_popup', self._w, x, y, entry)34963497def activate(self, index):3498"""Activate entry at INDEX."""3499self.tk.call(self._w, 'activate', index)35003501def add(self, itemType, cnf={}, **kw):3502"""Internal function."""3503self.tk.call((self._w, 'add', itemType) +3504self._options(cnf, kw))35053506def add_cascade(self, cnf={}, **kw):3507"""Add hierarchical menu item."""3508self.add('cascade', cnf or kw)35093510def add_checkbutton(self, cnf={}, **kw):3511"""Add checkbutton menu item."""3512self.add('checkbutton', cnf or kw)35133514def add_command(self, cnf={}, **kw):3515"""Add command menu item."""3516self.add('command', cnf or kw)35173518def add_radiobutton(self, cnf={}, **kw):3519"""Add radio menu item."""3520self.add('radiobutton', cnf or kw)35213522def add_separator(self, cnf={}, **kw):3523"""Add separator."""3524self.add('separator', cnf or kw)35253526def insert(self, index, itemType, cnf={}, **kw):3527"""Internal function."""3528self.tk.call((self._w, 'insert', index, itemType) +3529self._options(cnf, kw))35303531def insert_cascade(self, index, cnf={}, **kw):3532"""Add hierarchical menu item at INDEX."""3533self.insert(index, 'cascade', cnf or kw)35343535def insert_checkbutton(self, index, cnf={}, **kw):3536"""Add checkbutton menu item at INDEX."""3537self.insert(index, 'checkbutton', cnf or kw)35383539def insert_command(self, index, cnf={}, **kw):3540"""Add command menu item at INDEX."""3541self.insert(index, 'command', cnf or kw)35423543def insert_radiobutton(self, index, cnf={}, **kw):3544"""Add radio menu item at INDEX."""3545self.insert(index, 'radiobutton', cnf or kw)35463547def insert_separator(self, index, cnf={}, **kw):3548"""Add separator at INDEX."""3549self.insert(index, 'separator', cnf or kw)35503551def delete(self, index1, index2=None):3552"""Delete menu items between INDEX1 and INDEX2 (included)."""3553if index2 is None:3554index2 = index135553556num_index1, num_index2 = self.index(index1), self.index(index2)3557if (num_index1 is None) or (num_index2 is None):3558num_index1, num_index2 = 0, -135593560for i in range(num_index1, num_index2 + 1):3561if 'command' in self.entryconfig(i):3562c = str(self.entrycget(i, 'command'))3563if c:3564self.deletecommand(c)3565self.tk.call(self._w, 'delete', index1, index2)35663567def entrycget(self, index, option):3568"""Return the resource value of a menu item for OPTION at INDEX."""3569return self.tk.call(self._w, 'entrycget', index, '-' + option)35703571def entryconfigure(self, index, cnf=None, **kw):3572"""Configure a menu item at INDEX."""3573return self._configure(('entryconfigure', index), cnf, kw)35743575entryconfig = entryconfigure35763577def index(self, index):3578"""Return the index of a menu item identified by INDEX."""3579i = self.tk.call(self._w, 'index', index)3580return None if i in ('', 'none') else self.tk.getint(i) # GH-103685.35813582def invoke(self, index):3583"""Invoke a menu item identified by INDEX and execute3584the associated command."""3585return self.tk.call(self._w, 'invoke', index)35863587def post(self, x, y):3588"""Display a menu at position X,Y."""3589self.tk.call(self._w, 'post', x, y)35903591def type(self, index):3592"""Return the type of the menu item at INDEX."""3593return self.tk.call(self._w, 'type', index)35943595def unpost(self):3596"""Unmap a menu."""3597self.tk.call(self._w, 'unpost')35983599def xposition(self, index): # new in Tk 8.53600"""Return the x-position of the leftmost pixel of the menu item3601at INDEX."""3602return self.tk.getint(self.tk.call(self._w, 'xposition', index))36033604def yposition(self, index):3605"""Return the y-position of the topmost pixel of the menu item at INDEX."""3606return self.tk.getint(self.tk.call(3607self._w, 'yposition', index))360836093610class Menubutton(Widget):3611"""Menubutton widget, obsolete since Tk8.0."""36123613def __init__(self, master=None, cnf={}, **kw):3614Widget.__init__(self, master, 'menubutton', cnf, kw)361536163617class Message(Widget):3618"""Message widget to display multiline text. Obsolete since Label does it too."""36193620def __init__(self, master=None, cnf={}, **kw):3621Widget.__init__(self, master, 'message', cnf, kw)362236233624class Radiobutton(Widget):3625"""Radiobutton widget which shows only one of several buttons in on-state."""36263627def __init__(self, master=None, cnf={}, **kw):3628"""Construct a radiobutton widget with the parent MASTER.36293630Valid resource names: activebackground, activeforeground, anchor,3631background, bd, bg, bitmap, borderwidth, command, cursor,3632disabledforeground, fg, font, foreground, height,3633highlightbackground, highlightcolor, highlightthickness, image,3634indicatoron, justify, padx, pady, relief, selectcolor, selectimage,3635state, takefocus, text, textvariable, underline, value, variable,3636width, wraplength."""3637Widget.__init__(self, master, 'radiobutton', cnf, kw)36383639def deselect(self):3640"""Put the button in off-state."""36413642self.tk.call(self._w, 'deselect')36433644def flash(self):3645"""Flash the button."""3646self.tk.call(self._w, 'flash')36473648def invoke(self):3649"""Toggle the button and invoke a command if given as resource."""3650return self.tk.call(self._w, 'invoke')36513652def select(self):3653"""Put the button in on-state."""3654self.tk.call(self._w, 'select')365536563657class Scale(Widget):3658"""Scale widget which can display a numerical scale."""36593660def __init__(self, master=None, cnf={}, **kw):3661"""Construct a scale widget with the parent MASTER.36623663Valid resource names: activebackground, background, bigincrement, bd,3664bg, borderwidth, command, cursor, digits, fg, font, foreground, from,3665highlightbackground, highlightcolor, highlightthickness, label,3666length, orient, relief, repeatdelay, repeatinterval, resolution,3667showvalue, sliderlength, sliderrelief, state, takefocus,3668tickinterval, to, troughcolor, variable, width."""3669Widget.__init__(self, master, 'scale', cnf, kw)36703671def get(self):3672"""Get the current value as integer or float."""3673value = self.tk.call(self._w, 'get')3674try:3675return self.tk.getint(value)3676except (ValueError, TypeError, TclError):3677return self.tk.getdouble(value)36783679def set(self, value):3680"""Set the value to VALUE."""3681self.tk.call(self._w, 'set', value)36823683def coords(self, value=None):3684"""Return a tuple (X,Y) of the point along the centerline of the3685trough that corresponds to VALUE or the current value if None is3686given."""36873688return self._getints(self.tk.call(self._w, 'coords', value))36893690def identify(self, x, y):3691"""Return where the point X,Y lies. Valid return values are "slider",3692"though1" and "though2"."""3693return self.tk.call(self._w, 'identify', x, y)369436953696class Scrollbar(Widget):3697"""Scrollbar widget which displays a slider at a certain position."""36983699def __init__(self, master=None, cnf={}, **kw):3700"""Construct a scrollbar widget with the parent MASTER.37013702Valid resource names: activebackground, activerelief,3703background, bd, bg, borderwidth, command, cursor,3704elementborderwidth, highlightbackground,3705highlightcolor, highlightthickness, jump, orient,3706relief, repeatdelay, repeatinterval, takefocus,3707troughcolor, width."""3708Widget.__init__(self, master, 'scrollbar', cnf, kw)37093710def activate(self, index=None):3711"""Marks the element indicated by index as active.3712The only index values understood by this method are "arrow1",3713"slider", or "arrow2". If any other value is specified then no3714element of the scrollbar will be active. If index is not specified,3715the method returns the name of the element that is currently active,3716or None if no element is active."""3717return self.tk.call(self._w, 'activate', index) or None37183719def delta(self, deltax, deltay):3720"""Return the fractional change of the scrollbar setting if it3721would be moved by DELTAX or DELTAY pixels."""3722return self.tk.getdouble(3723self.tk.call(self._w, 'delta', deltax, deltay))37243725def fraction(self, x, y):3726"""Return the fractional value which corresponds to a slider3727position of X,Y."""3728return self.tk.getdouble(self.tk.call(self._w, 'fraction', x, y))37293730def identify(self, x, y):3731"""Return the element under position X,Y as one of3732"arrow1","slider","arrow2" or ""."""3733return self.tk.call(self._w, 'identify', x, y)37343735def get(self):3736"""Return the current fractional values (upper and lower end)3737of the slider position."""3738return self._getdoubles(self.tk.call(self._w, 'get'))37393740def set(self, first, last):3741"""Set the fractional values of the slider position (upper and3742lower ends as value between 0 and 1)."""3743self.tk.call(self._w, 'set', first, last)374437453746class Text(Widget, XView, YView):3747"""Text widget which can display text in various forms."""37483749def __init__(self, master=None, cnf={}, **kw):3750"""Construct a text widget with the parent MASTER.37513752STANDARD OPTIONS37533754background, borderwidth, cursor,3755exportselection, font, foreground,3756highlightbackground, highlightcolor,3757highlightthickness, insertbackground,3758insertborderwidth, insertofftime,3759insertontime, insertwidth, padx, pady,3760relief, selectbackground,3761selectborderwidth, selectforeground,3762setgrid, takefocus,3763xscrollcommand, yscrollcommand,37643765WIDGET-SPECIFIC OPTIONS37663767autoseparators, height, maxundo,3768spacing1, spacing2, spacing3,3769state, tabs, undo, width, wrap,37703771"""3772Widget.__init__(self, master, 'text', cnf, kw)37733774def bbox(self, index):3775"""Return a tuple of (x,y,width,height) which gives the bounding3776box of the visible part of the character at the given index."""3777return self._getints(3778self.tk.call(self._w, 'bbox', index)) or None37793780def compare(self, index1, op, index2):3781"""Return whether between index INDEX1 and index INDEX2 the3782relation OP is satisfied. OP is one of <, <=, ==, >=, >, or !=."""3783return self.tk.getboolean(self.tk.call(3784self._w, 'compare', index1, op, index2))37853786def count(self, index1, index2, *options, return_ints=False): # new in Tk 8.53787"""Counts the number of relevant things between the two indices.37883789If INDEX1 is after INDEX2, the result will be a negative number3790(and this holds for each of the possible options).37913792The actual items which are counted depends on the options given.3793The result is a tuple of integers, one for the result of each3794counting option given, if more than one option is specified or3795return_ints is false (default), otherwise it is an integer.3796Valid counting options are "chars", "displaychars",3797"displayindices", "displaylines", "indices", "lines", "xpixels"3798and "ypixels". The default value, if no option is specified, is3799"indices". There is an additional possible option "update",3800which if given then all subsequent options ensure that any3801possible out of date information is recalculated.3802"""3803options = ['-%s' % arg for arg in options]3804res = self.tk.call(self._w, 'count', *options, index1, index2)3805if not isinstance(res, int):3806res = self._getints(res)3807if len(res) == 1:3808res, = res3809if not return_ints:3810if not res:3811res = None3812elif len(options) <= 1:3813res = (res,)3814return res38153816def debug(self, boolean=None):3817"""Turn on the internal consistency checks of the B-Tree inside the text3818widget according to BOOLEAN."""3819if boolean is None:3820return self.tk.getboolean(self.tk.call(self._w, 'debug'))3821self.tk.call(self._w, 'debug', boolean)38223823def delete(self, index1, index2=None):3824"""Delete the characters between INDEX1 and INDEX2 (not included)."""3825self.tk.call(self._w, 'delete', index1, index2)38263827def dlineinfo(self, index):3828"""Return tuple (x,y,width,height,baseline) giving the bounding box3829and baseline position of the visible part of the line containing3830the character at INDEX."""3831return self._getints(self.tk.call(self._w, 'dlineinfo', index))38323833def dump(self, index1, index2=None, command=None, **kw):3834"""Return the contents of the widget between index1 and index2.38353836The type of contents returned in filtered based on the keyword3837parameters; if 'all', 'image', 'mark', 'tag', 'text', or 'window' are3838given and true, then the corresponding items are returned. The result3839is a list of triples of the form (key, value, index). If none of the3840keywords are true then 'all' is used by default.38413842If the 'command' argument is given, it is called once for each element3843of the list of triples, with the values of each triple serving as the3844arguments to the function. In this case the list is not returned."""3845args = []3846func_name = None3847result = None3848if not command:3849# Never call the dump command without the -command flag, since the3850# output could involve Tcl quoting and would be a pain to parse3851# right. Instead just set the command to build a list of triples3852# as if we had done the parsing.3853result = []3854def append_triple(key, value, index, result=result):3855result.append((key, value, index))3856command = append_triple3857try:3858if not isinstance(command, str):3859func_name = command = self._register(command)3860args += ["-command", command]3861for key in kw:3862if kw[key]: args.append("-" + key)3863args.append(index1)3864if index2:3865args.append(index2)3866self.tk.call(self._w, "dump", *args)3867return result3868finally:3869if func_name:3870self.deletecommand(func_name)38713872## new in tk8.43873def edit(self, *args):3874"""Internal method38753876This method controls the undo mechanism and3877the modified flag. The exact behavior of the3878command depends on the option argument that3879follows the edit argument. The following forms3880of the command are currently supported:38813882edit_modified, edit_redo, edit_reset, edit_separator3883and edit_undo38843885"""3886return self.tk.call(self._w, 'edit', *args)38873888def edit_modified(self, arg=None):3889"""Get or Set the modified flag38903891If arg is not specified, returns the modified3892flag of the widget. The insert, delete, edit undo and3893edit redo commands or the user can set or clear the3894modified flag. If boolean is specified, sets the3895modified flag of the widget to arg.3896"""3897return self.edit("modified", arg)38983899def edit_redo(self):3900"""Redo the last undone edit39013902When the undo option is true, reapplies the last3903undone edits provided no other edits were done since3904then. Generates an error when the redo stack is empty.3905Does nothing when the undo option is false.3906"""3907return self.edit("redo")39083909def edit_reset(self):3910"""Clears the undo and redo stacks3911"""3912return self.edit("reset")39133914def edit_separator(self):3915"""Inserts a separator (boundary) on the undo stack.39163917Does nothing when the undo option is false3918"""3919return self.edit("separator")39203921def edit_undo(self):3922"""Undoes the last edit action39233924If the undo option is true. An edit action is defined3925as all the insert and delete commands that are recorded3926on the undo stack in between two separators. Generates3927an error when the undo stack is empty. Does nothing3928when the undo option is false3929"""3930return self.edit("undo")39313932def get(self, index1, index2=None):3933"""Return the text from INDEX1 to INDEX2 (not included)."""3934return self.tk.call(self._w, 'get', index1, index2)3935# (Image commands are new in 8.0)39363937def image_cget(self, index, option):3938"""Return the value of OPTION of an embedded image at INDEX."""3939if option[:1] != "-":3940option = "-" + option3941if option[-1:] == "_":3942option = option[:-1]3943return self.tk.call(self._w, "image", "cget", index, option)39443945def image_configure(self, index, cnf=None, **kw):3946"""Configure an embedded image at INDEX."""3947return self._configure(('image', 'configure', index), cnf, kw)39483949def image_create(self, index, cnf={}, **kw):3950"""Create an embedded image at INDEX."""3951return self.tk.call(3952self._w, "image", "create", index,3953*self._options(cnf, kw))39543955def image_names(self):3956"""Return all names of embedded images in this widget."""3957return self.tk.call(self._w, "image", "names")39583959def index(self, index):3960"""Return the index in the form line.char for INDEX."""3961return str(self.tk.call(self._w, 'index', index))39623963def insert(self, index, chars, *args):3964"""Insert CHARS before the characters at INDEX. An additional3965tag can be given in ARGS. Additional CHARS and tags can follow in ARGS."""3966self.tk.call((self._w, 'insert', index, chars) + args)39673968def mark_gravity(self, markName, direction=None):3969"""Change the gravity of a mark MARKNAME to DIRECTION (LEFT or RIGHT).3970Return the current value if None is given for DIRECTION."""3971return self.tk.call(3972(self._w, 'mark', 'gravity', markName, direction))39733974def mark_names(self):3975"""Return all mark names."""3976return self.tk.splitlist(self.tk.call(3977self._w, 'mark', 'names'))39783979def mark_set(self, markName, index):3980"""Set mark MARKNAME before the character at INDEX."""3981self.tk.call(self._w, 'mark', 'set', markName, index)39823983def mark_unset(self, *markNames):3984"""Delete all marks in MARKNAMES."""3985self.tk.call((self._w, 'mark', 'unset') + markNames)39863987def mark_next(self, index):3988"""Return the name of the next mark after INDEX."""3989return self.tk.call(self._w, 'mark', 'next', index) or None39903991def mark_previous(self, index):3992"""Return the name of the previous mark before INDEX."""3993return self.tk.call(self._w, 'mark', 'previous', index) or None39943995def peer_create(self, newPathName, cnf={}, **kw): # new in Tk 8.53996"""Creates a peer text widget with the given newPathName, and any3997optional standard configuration options. By default the peer will3998have the same start and end line as the parent widget, but3999these can be overridden with the standard configuration options."""4000self.tk.call(self._w, 'peer', 'create', newPathName,4001*self._options(cnf, kw))40024003def peer_names(self): # new in Tk 8.54004"""Returns a list of peers of this widget (this does not include4005the widget itself)."""4006return self.tk.splitlist(self.tk.call(self._w, 'peer', 'names'))40074008def replace(self, index1, index2, chars, *args): # new in Tk 8.54009"""Replaces the range of characters between index1 and index2 with4010the given characters and tags specified by args.40114012See the method insert for some more information about args, and the4013method delete for information about the indices."""4014self.tk.call(self._w, 'replace', index1, index2, chars, *args)40154016def scan_mark(self, x, y):4017"""Remember the current X, Y coordinates."""4018self.tk.call(self._w, 'scan', 'mark', x, y)40194020def scan_dragto(self, x, y):4021"""Adjust the view of the text to 10 times the4022difference between X and Y and the coordinates given in4023scan_mark."""4024self.tk.call(self._w, 'scan', 'dragto', x, y)40254026def search(self, pattern, index, stopindex=None,4027forwards=None, backwards=None, exact=None,4028regexp=None, nocase=None, count=None, elide=None):4029"""Search PATTERN beginning from INDEX until STOPINDEX.4030Return the index of the first character of a match or an4031empty string."""4032args = [self._w, 'search']4033if forwards: args.append('-forwards')4034if backwards: args.append('-backwards')4035if exact: args.append('-exact')4036if regexp: args.append('-regexp')4037if nocase: args.append('-nocase')4038if elide: args.append('-elide')4039if count: args.append('-count'); args.append(count)4040if pattern and pattern[0] == '-': args.append('--')4041args.append(pattern)4042args.append(index)4043if stopindex: args.append(stopindex)4044return str(self.tk.call(tuple(args)))40454046def see(self, index):4047"""Scroll such that the character at INDEX is visible."""4048self.tk.call(self._w, 'see', index)40494050def tag_add(self, tagName, index1, *args):4051"""Add tag TAGNAME to all characters between INDEX1 and index2 in ARGS.4052Additional pairs of indices may follow in ARGS."""4053self.tk.call(4054(self._w, 'tag', 'add', tagName, index1) + args)40554056def tag_unbind(self, tagName, sequence, funcid=None):4057"""Unbind for all characters with TAGNAME for event SEQUENCE the4058function identified with FUNCID."""4059return self._unbind((self._w, 'tag', 'bind', tagName, sequence), funcid)40604061def tag_bind(self, tagName, sequence, func, add=None):4062"""Bind to all characters with TAGNAME at event SEQUENCE a call to function FUNC.40634064An additional boolean parameter ADD specifies whether FUNC will be4065called additionally to the other bound function or whether it will4066replace the previous function. See bind for the return value."""4067return self._bind((self._w, 'tag', 'bind', tagName),4068sequence, func, add)40694070def _tag_bind(self, tagName, sequence=None, func=None, add=None):4071# For tests only4072return self._bind((self._w, 'tag', 'bind', tagName),4073sequence, func, add)40744075def tag_cget(self, tagName, option):4076"""Return the value of OPTION for tag TAGNAME."""4077if option[:1] != '-':4078option = '-' + option4079if option[-1:] == '_':4080option = option[:-1]4081return self.tk.call(self._w, 'tag', 'cget', tagName, option)40824083def tag_configure(self, tagName, cnf=None, **kw):4084"""Configure a tag TAGNAME."""4085return self._configure(('tag', 'configure', tagName), cnf, kw)40864087tag_config = tag_configure40884089def tag_delete(self, *tagNames):4090"""Delete all tags in TAGNAMES."""4091self.tk.call((self._w, 'tag', 'delete') + tagNames)40924093def tag_lower(self, tagName, belowThis=None):4094"""Change the priority of tag TAGNAME such that it is lower4095than the priority of BELOWTHIS."""4096self.tk.call(self._w, 'tag', 'lower', tagName, belowThis)40974098def tag_names(self, index=None):4099"""Return a list of all tag names."""4100return self.tk.splitlist(4101self.tk.call(self._w, 'tag', 'names', index))41024103def tag_nextrange(self, tagName, index1, index2=None):4104"""Return a list of start and end index for the first sequence of4105characters between INDEX1 and INDEX2 which all have tag TAGNAME.4106The text is searched forward from INDEX1."""4107return self.tk.splitlist(self.tk.call(4108self._w, 'tag', 'nextrange', tagName, index1, index2))41094110def tag_prevrange(self, tagName, index1, index2=None):4111"""Return a list of start and end index for the first sequence of4112characters between INDEX1 and INDEX2 which all have tag TAGNAME.4113The text is searched backwards from INDEX1."""4114return self.tk.splitlist(self.tk.call(4115self._w, 'tag', 'prevrange', tagName, index1, index2))41164117def tag_raise(self, tagName, aboveThis=None):4118"""Change the priority of tag TAGNAME such that it is higher4119than the priority of ABOVETHIS."""4120self.tk.call(4121self._w, 'tag', 'raise', tagName, aboveThis)41224123def tag_ranges(self, tagName):4124"""Return a list of ranges of text which have tag TAGNAME."""4125return self.tk.splitlist(self.tk.call(4126self._w, 'tag', 'ranges', tagName))41274128def tag_remove(self, tagName, index1, index2=None):4129"""Remove tag TAGNAME from all characters between INDEX1 and INDEX2."""4130self.tk.call(4131self._w, 'tag', 'remove', tagName, index1, index2)41324133def window_cget(self, index, option):4134"""Return the value of OPTION of an embedded window at INDEX."""4135if option[:1] != '-':4136option = '-' + option4137if option[-1:] == '_':4138option = option[:-1]4139return self.tk.call(self._w, 'window', 'cget', index, option)41404141def window_configure(self, index, cnf=None, **kw):4142"""Configure an embedded window at INDEX."""4143return self._configure(('window', 'configure', index), cnf, kw)41444145window_config = window_configure41464147def window_create(self, index, cnf={}, **kw):4148"""Create a window at INDEX."""4149self.tk.call(4150(self._w, 'window', 'create', index)4151+ self._options(cnf, kw))41524153def window_names(self):4154"""Return all names of embedded windows in this widget."""4155return self.tk.splitlist(4156self.tk.call(self._w, 'window', 'names'))41574158def yview_pickplace(self, *what):4159"""Obsolete function, use see."""4160self.tk.call((self._w, 'yview', '-pickplace') + what)416141624163class _setit:4164"""Internal class. It wraps the command in the widget OptionMenu."""41654166def __init__(self, var, value, callback=None):4167self.__value = value4168self.__var = var4169self.__callback = callback41704171def __call__(self, *args):4172self.__var.set(self.__value)4173if self.__callback is not None:4174self.__callback(self.__value, *args)417541764177class OptionMenu(Menubutton):4178"""OptionMenu which allows the user to select a value from a menu."""41794180def __init__(self, master, variable, value, *values, **kwargs):4181"""Construct an optionmenu widget with the parent MASTER, with4182the resource textvariable set to VARIABLE, the initially selected4183value VALUE, the other menu values VALUES and an additional4184keyword argument command."""4185kw = {"borderwidth": 2, "textvariable": variable,4186"indicatoron": 1, "relief": RAISED, "anchor": "c",4187"highlightthickness": 2}4188Widget.__init__(self, master, "menubutton", kw)4189self.widgetName = 'tk_optionMenu'4190menu = self.__menu = Menu(self, name="menu", tearoff=0)4191self.menuname = menu._w4192# 'command' is the only supported keyword4193callback = kwargs.get('command')4194if 'command' in kwargs:4195del kwargs['command']4196if kwargs:4197raise TclError('unknown option -'+next(iter(kwargs)))4198menu.add_command(label=value,4199command=_setit(variable, value, callback))4200for v in values:4201menu.add_command(label=v,4202command=_setit(variable, v, callback))4203self["menu"] = menu42044205def __getitem__(self, name):4206if name == 'menu':4207return self.__menu4208return Widget.__getitem__(self, name)42094210def destroy(self):4211"""Destroy this widget and the associated menu."""4212Menubutton.destroy(self)4213self.__menu = None421442154216class Image:4217"""Base class for images."""4218_last_id = 042194220def __init__(self, imgtype, name=None, cnf={}, master=None, **kw):4221self.name = None4222if master is None:4223master = _get_default_root('create image')4224self.tk = getattr(master, 'tk', master)4225if not name:4226Image._last_id += 14227name = "pyimage%r" % (Image._last_id,) # tk itself would use image<x>4228if kw and cnf: cnf = _cnfmerge((cnf, kw))4229elif kw: cnf = kw4230options = ()4231for k, v in cnf.items():4232options = options + ('-'+k, v)4233self.tk.call(('image', 'create', imgtype, name,) + options)4234self.name = name42354236def __str__(self): return self.name42374238def __del__(self):4239if self.name:4240try:4241self.tk.call('image', 'delete', self.name)4242except TclError:4243# May happen if the root was destroyed4244pass42454246def __setitem__(self, key, value):4247self.tk.call(self.name, 'configure', '-'+key, value)42484249def __getitem__(self, key):4250return self.tk.call(self.name, 'configure', '-'+key)42514252def configure(self, **kw):4253"""Configure the image."""4254res = ()4255for k, v in _cnfmerge(kw).items():4256if v is not None:4257if k[-1] == '_': k = k[:-1]4258res = res + ('-'+k, v)4259self.tk.call((self.name, 'config') + res)42604261config = configure42624263def height(self):4264"""Return the height of the image."""4265return self.tk.getint(4266self.tk.call('image', 'height', self.name))42674268def type(self):4269"""Return the type of the image, e.g. "photo" or "bitmap"."""4270return self.tk.call('image', 'type', self.name)42714272def width(self):4273"""Return the width of the image."""4274return self.tk.getint(4275self.tk.call('image', 'width', self.name))427642774278class PhotoImage(Image):4279"""Widget which can display images in PGM, PPM, GIF, PNG format."""42804281def __init__(self, name=None, cnf={}, master=None, **kw):4282"""Create an image with NAME.42834284Valid resource names: data, format, file, gamma, height, palette,4285width."""4286Image.__init__(self, 'photo', name, cnf, master, **kw)42874288def blank(self):4289"""Display a transparent image."""4290self.tk.call(self.name, 'blank')42914292def cget(self, option):4293"""Return the value of OPTION."""4294return self.tk.call(self.name, 'cget', '-' + option)4295# XXX config42964297def __getitem__(self, key):4298return self.tk.call(self.name, 'cget', '-' + key)42994300def copy(self, *, from_coords=None, zoom=None, subsample=None):4301"""Return a new PhotoImage with the same image as this widget.43024303The FROM_COORDS option specifies a rectangular sub-region of the4304source image to be copied. It must be a tuple or a list of 1 to 44305integers (x1, y1, x2, y2). (x1, y1) and (x2, y2) specify diagonally4306opposite corners of the rectangle. If x2 and y2 are not specified,4307the default value is the bottom-right corner of the source image.4308The pixels copied will include the left and top edges of the4309specified rectangle but not the bottom or right edges. If the4310FROM_COORDS option is not given, the default is the whole source4311image.43124313If SUBSAMPLE or ZOOM are specified, the image is transformed as in4314the subsample() or zoom() methods. The value must be a single4315integer or a pair of integers.4316"""4317destImage = PhotoImage(master=self.tk)4318destImage.copy_replace(self, from_coords=from_coords,4319zoom=zoom, subsample=subsample)4320return destImage43214322def zoom(self, x, y='', *, from_coords=None):4323"""Return a new PhotoImage with the same image as this widget4324but zoom it with a factor of X in the X direction and Y in the Y4325direction. If Y is not given, the default value is the same as X.43264327The FROM_COORDS option specifies a rectangular sub-region of the4328source image to be copied, as in the copy() method.4329"""4330if y=='': y=x4331return self.copy(zoom=(x, y), from_coords=from_coords)43324333def subsample(self, x, y='', *, from_coords=None):4334"""Return a new PhotoImage based on the same image as this widget4335but use only every Xth or Yth pixel. If Y is not given, the4336default value is the same as X.43374338The FROM_COORDS option specifies a rectangular sub-region of the4339source image to be copied, as in the copy() method.4340"""4341if y=='': y=x4342return self.copy(subsample=(x, y), from_coords=from_coords)43434344def copy_replace(self, sourceImage, *, from_coords=None, to=None, shrink=False,4345zoom=None, subsample=None, compositingrule=None):4346"""Copy a region from the source image (which must be a PhotoImage) to4347this image, possibly with pixel zooming and/or subsampling. If no4348options are specified, this command copies the whole of the source4349image into this image, starting at coordinates (0, 0).43504351The FROM_COORDS option specifies a rectangular sub-region of the4352source image to be copied. It must be a tuple or a list of 1 to 44353integers (x1, y1, x2, y2). (x1, y1) and (x2, y2) specify diagonally4354opposite corners of the rectangle. If x2 and y2 are not specified,4355the default value is the bottom-right corner of the source image.4356The pixels copied will include the left and top edges of the4357specified rectangle but not the bottom or right edges. If the4358FROM_COORDS option is not given, the default is the whole source4359image.43604361The TO option specifies a rectangular sub-region of the destination4362image to be affected. It must be a tuple or a list of 1 to 44363integers (x1, y1, x2, y2). (x1, y1) and (x2, y2) specify diagonally4364opposite corners of the rectangle. If x2 and y2 are not specified,4365the default value is (x1,y1) plus the size of the source region4366(after subsampling and zooming, if specified). If x2 and y2 are4367specified, the source region will be replicated if necessary to fill4368the destination region in a tiled fashion.43694370If SHRINK is true, the size of the destination image should be4371reduced, if necessary, so that the region being copied into is at4372the bottom-right corner of the image.43734374If SUBSAMPLE or ZOOM are specified, the image is transformed as in4375the subsample() or zoom() methods. The value must be a single4376integer or a pair of integers.43774378The COMPOSITINGRULE option specifies how transparent pixels in the4379source image are combined with the destination image. When a4380compositing rule of 'overlay' is set, the old contents of the4381destination image are visible, as if the source image were printed4382on a piece of transparent film and placed over the top of the4383destination. When a compositing rule of 'set' is set, the old4384contents of the destination image are discarded and the source image4385is used as-is. The default compositing rule is 'overlay'.4386"""4387options = []4388if from_coords is not None:4389options.extend(('-from', *from_coords))4390if to is not None:4391options.extend(('-to', *to))4392if shrink:4393options.append('-shrink')4394if zoom is not None:4395if not isinstance(zoom, (tuple, list)):4396zoom = (zoom,)4397options.extend(('-zoom', *zoom))4398if subsample is not None:4399if not isinstance(subsample, (tuple, list)):4400subsample = (subsample,)4401options.extend(('-subsample', *subsample))4402if compositingrule:4403options.extend(('-compositingrule', compositingrule))4404self.tk.call(self.name, 'copy', sourceImage, *options)44054406def get(self, x, y):4407"""Return the color (red, green, blue) of the pixel at X,Y."""4408return self.tk.call(self.name, 'get', x, y)44094410def put(self, data, to=None):4411"""Put row formatted colors to image starting from4412position TO, e.g. image.put("{red green} {blue yellow}", to=(4,6))"""4413args = (self.name, 'put', data)4414if to:4415if to[0] == '-to':4416to = to[1:]4417args = args + ('-to',) + tuple(to)4418self.tk.call(args)44194420def read(self, filename, format=None, *, from_coords=None, to=None, shrink=False):4421"""Reads image data from the file named FILENAME into the image.44224423The FORMAT option specifies the format of the image data in the4424file.44254426The FROM_COORDS option specifies a rectangular sub-region of the image4427file data to be copied to the destination image. It must be a tuple4428or a list of 1 to 4 integers (x1, y1, x2, y2). (x1, y1) and4429(x2, y2) specify diagonally opposite corners of the rectangle. If4430x2 and y2 are not specified, the default value is the bottom-right4431corner of the source image. The default, if this option is not4432specified, is the whole of the image in the image file.44334434The TO option specifies the coordinates of the top-left corner of4435the region of the image into which data from filename are to be4436read. The default is (0, 0).44374438If SHRINK is true, the size of the destination image will be4439reduced, if necessary, so that the region into which the image file4440data are read is at the bottom-right corner of the image.4441"""4442options = ()4443if format is not None:4444options += ('-format', format)4445if from_coords is not None:4446options += ('-from', *from_coords)4447if shrink:4448options += ('-shrink',)4449if to is not None:4450options += ('-to', *to)4451self.tk.call(self.name, 'read', filename, *options)44524453def write(self, filename, format=None, from_coords=None, *,4454background=None, grayscale=False):4455"""Writes image data from the image to a file named FILENAME.44564457The FORMAT option specifies the name of the image file format4458handler to be used to write the data to the file. If this option4459is not given, the format is guessed from the file extension.44604461The FROM_COORDS option specifies a rectangular region of the image4462to be written to the image file. It must be a tuple or a list of 14463to 4 integers (x1, y1, x2, y2). If only x1 and y1 are specified,4464the region extends from (x1,y1) to the bottom-right corner of the4465image. If all four coordinates are given, they specify diagonally4466opposite corners of the rectangular region. The default, if this4467option is not given, is the whole image.44684469If BACKGROUND is specified, the data will not contain any4470transparency information. In all transparent pixels the color will4471be replaced by the specified color.44724473If GRAYSCALE is true, the data will not contain color information.4474All pixel data will be transformed into grayscale.4475"""4476options = ()4477if format is not None:4478options += ('-format', format)4479if from_coords is not None:4480options += ('-from', *from_coords)4481if grayscale:4482options += ('-grayscale',)4483if background is not None:4484options += ('-background', background)4485self.tk.call(self.name, 'write', filename, *options)44864487def data(self, format=None, *, from_coords=None,4488background=None, grayscale=False):4489"""Returns image data.44904491The FORMAT option specifies the name of the image file format4492handler to be used. If this option is not given, this method uses4493a format that consists of a tuple (one element per row) of strings4494containing space-separated (one element per pixel/column) colors4495in “#RRGGBB” format (where RR is a pair of hexadecimal digits for4496the red channel, GG for green, and BB for blue).44974498The FROM_COORDS option specifies a rectangular region of the image4499to be returned. It must be a tuple or a list of 1 to 4 integers4500(x1, y1, x2, y2). If only x1 and y1 are specified, the region4501extends from (x1,y1) to the bottom-right corner of the image. If4502all four coordinates are given, they specify diagonally opposite4503corners of the rectangular region, including (x1, y1) and excluding4504(x2, y2). The default, if this option is not given, is the whole4505image.45064507If BACKGROUND is specified, the data will not contain any4508transparency information. In all transparent pixels the color will4509be replaced by the specified color.45104511If GRAYSCALE is true, the data will not contain color information.4512All pixel data will be transformed into grayscale.4513"""4514options = ()4515if format is not None:4516options += ('-format', format)4517if from_coords is not None:4518options += ('-from', *from_coords)4519if grayscale:4520options += ('-grayscale',)4521if background is not None:4522options += ('-background', background)4523data = self.tk.call(self.name, 'data', *options)4524if isinstance(data, str): # For wantobjects = 0.4525if format is None:4526data = self.tk.splitlist(data)4527else:4528data = bytes(data, 'latin1')4529return data45304531def transparency_get(self, x, y):4532"""Return True if the pixel at x,y is transparent."""4533return self.tk.getboolean(self.tk.call(4534self.name, 'transparency', 'get', x, y))45354536def transparency_set(self, x, y, boolean):4537"""Set the transparency of the pixel at x,y."""4538self.tk.call(self.name, 'transparency', 'set', x, y, boolean)453945404541class BitmapImage(Image):4542"""Widget which can display images in XBM format."""45434544def __init__(self, name=None, cnf={}, master=None, **kw):4545"""Create a bitmap with NAME.45464547Valid resource names: background, data, file, foreground, maskdata, maskfile."""4548Image.__init__(self, 'bitmap', name, cnf, master, **kw)454945504551def image_names():4552tk = _get_default_root('use image_names()').tk4553return tk.splitlist(tk.call('image', 'names'))455445554556def image_types():4557tk = _get_default_root('use image_types()').tk4558return tk.splitlist(tk.call('image', 'types'))455945604561class Spinbox(Widget, XView):4562"""spinbox widget."""45634564def __init__(self, master=None, cnf={}, **kw):4565"""Construct a spinbox widget with the parent MASTER.45664567STANDARD OPTIONS45684569activebackground, background, borderwidth,4570cursor, exportselection, font, foreground,4571highlightbackground, highlightcolor,4572highlightthickness, insertbackground,4573insertborderwidth, insertofftime,4574insertontime, insertwidth, justify, relief,4575repeatdelay, repeatinterval,4576selectbackground, selectborderwidth4577selectforeground, takefocus, textvariable4578xscrollcommand.45794580WIDGET-SPECIFIC OPTIONS45814582buttonbackground, buttoncursor,4583buttondownrelief, buttonuprelief,4584command, disabledbackground,4585disabledforeground, format, from,4586invalidcommand, increment,4587readonlybackground, state, to,4588validate, validatecommand values,4589width, wrap,4590"""4591Widget.__init__(self, master, 'spinbox', cnf, kw)45924593def bbox(self, index):4594"""Return a tuple of X1,Y1,X2,Y2 coordinates for a4595rectangle which encloses the character given by index.45964597The first two elements of the list give the x and y4598coordinates of the upper-left corner of the screen4599area covered by the character (in pixels relative4600to the widget) and the last two elements give the4601width and height of the character, in pixels. The4602bounding box may refer to a region outside the4603visible area of the window.4604"""4605return self._getints(self.tk.call(self._w, 'bbox', index)) or None46064607def delete(self, first, last=None):4608"""Delete one or more elements of the spinbox.46094610First is the index of the first character to delete,4611and last is the index of the character just after4612the last one to delete. If last isn't specified it4613defaults to first+1, i.e. a single character is4614deleted. This command returns an empty string.4615"""4616return self.tk.call(self._w, 'delete', first, last)46174618def get(self):4619"""Returns the spinbox's string"""4620return self.tk.call(self._w, 'get')46214622def icursor(self, index):4623"""Alter the position of the insertion cursor.46244625The insertion cursor will be displayed just before4626the character given by index. Returns an empty string4627"""4628return self.tk.call(self._w, 'icursor', index)46294630def identify(self, x, y):4631"""Returns the name of the widget at position x, y46324633Return value is one of: none, buttondown, buttonup, entry4634"""4635return self.tk.call(self._w, 'identify', x, y)46364637def index(self, index):4638"""Returns the numerical index corresponding to index4639"""4640return self.tk.call(self._w, 'index', index)46414642def insert(self, index, s):4643"""Insert string s at index46444645Returns an empty string.4646"""4647return self.tk.call(self._w, 'insert', index, s)46484649def invoke(self, element):4650"""Causes the specified element to be invoked46514652The element could be buttondown or buttonup4653triggering the action associated with it.4654"""4655return self.tk.call(self._w, 'invoke', element)46564657def scan(self, *args):4658"""Internal function."""4659return self._getints(4660self.tk.call((self._w, 'scan') + args)) or ()46614662def scan_mark(self, x):4663"""Records x and the current view in the spinbox window;46644665used in conjunction with later scan dragto commands.4666Typically this command is associated with a mouse button4667press in the widget. It returns an empty string.4668"""4669return self.scan("mark", x)46704671def scan_dragto(self, x):4672"""Compute the difference between the given x argument4673and the x argument to the last scan mark command46744675It then adjusts the view left or right by 10 times the4676difference in x-coordinates. This command is typically4677associated with mouse motion events in the widget, to4678produce the effect of dragging the spinbox at high speed4679through the window. The return value is an empty string.4680"""4681return self.scan("dragto", x)46824683def selection(self, *args):4684"""Internal function."""4685return self._getints(4686self.tk.call((self._w, 'selection') + args)) or ()46874688def selection_adjust(self, index):4689"""Locate the end of the selection nearest to the character4690given by index,46914692Then adjust that end of the selection to be at index4693(i.e including but not going beyond index). The other4694end of the selection is made the anchor point for future4695select to commands. If the selection isn't currently in4696the spinbox, then a new selection is created to include4697the characters between index and the most recent selection4698anchor point, inclusive.4699"""4700return self.selection("adjust", index)47014702def selection_clear(self):4703"""Clear the selection47044705If the selection isn't in this widget then the4706command has no effect.4707"""4708return self.selection("clear")47094710def selection_element(self, element=None):4711"""Sets or gets the currently selected element.47124713If a spinbutton element is specified, it will be4714displayed depressed.4715"""4716return self.tk.call(self._w, 'selection', 'element', element)47174718def selection_from(self, index):4719"""Set the fixed end of a selection to INDEX."""4720self.selection('from', index)47214722def selection_present(self):4723"""Return True if there are characters selected in the spinbox, False4724otherwise."""4725return self.tk.getboolean(4726self.tk.call(self._w, 'selection', 'present'))47274728def selection_range(self, start, end):4729"""Set the selection from START to END (not included)."""4730self.selection('range', start, end)47314732def selection_to(self, index):4733"""Set the variable end of a selection to INDEX."""4734self.selection('to', index)47354736###########################################################################473747384739class LabelFrame(Widget):4740"""labelframe widget."""47414742def __init__(self, master=None, cnf={}, **kw):4743"""Construct a labelframe widget with the parent MASTER.47444745STANDARD OPTIONS47464747borderwidth, cursor, font, foreground,4748highlightbackground, highlightcolor,4749highlightthickness, padx, pady, relief,4750takefocus, text47514752WIDGET-SPECIFIC OPTIONS47534754background, class, colormap, container,4755height, labelanchor, labelwidget,4756visual, width4757"""4758Widget.__init__(self, master, 'labelframe', cnf, kw)47594760########################################################################476147624763class PanedWindow(Widget):4764"""panedwindow widget."""47654766def __init__(self, master=None, cnf={}, **kw):4767"""Construct a panedwindow widget with the parent MASTER.47684769STANDARD OPTIONS47704771background, borderwidth, cursor, height,4772orient, relief, width47734774WIDGET-SPECIFIC OPTIONS47754776handlepad, handlesize, opaqueresize,4777sashcursor, sashpad, sashrelief,4778sashwidth, showhandle,4779"""4780Widget.__init__(self, master, 'panedwindow', cnf, kw)47814782def add(self, child, **kw):4783"""Add a child widget to the panedwindow in a new pane.47844785The child argument is the name of the child widget4786followed by pairs of arguments that specify how to4787manage the windows. The possible options and values4788are the ones accepted by the paneconfigure method.4789"""4790self.tk.call((self._w, 'add', child) + self._options(kw))47914792def remove(self, child):4793"""Remove the pane containing child from the panedwindow47944795All geometry management options for child will be forgotten.4796"""4797self.tk.call(self._w, 'forget', child)47984799forget = remove48004801def identify(self, x, y):4802"""Identify the panedwindow component at point x, y48034804If the point is over a sash or a sash handle, the result4805is a two element list containing the index of the sash or4806handle, and a word indicating whether it is over a sash4807or a handle, such as {0 sash} or {2 handle}. If the point4808is over any other part of the panedwindow, the result is4809an empty list.4810"""4811return self.tk.call(self._w, 'identify', x, y)48124813def proxy(self, *args):4814"""Internal function."""4815return self._getints(4816self.tk.call((self._w, 'proxy') + args)) or ()48174818def proxy_coord(self):4819"""Return the x and y pair of the most recent proxy location4820"""4821return self.proxy("coord")48224823def proxy_forget(self):4824"""Remove the proxy from the display.4825"""4826return self.proxy("forget")48274828def proxy_place(self, x, y):4829"""Place the proxy at the given x and y coordinates.4830"""4831return self.proxy("place", x, y)48324833def sash(self, *args):4834"""Internal function."""4835return self._getints(4836self.tk.call((self._w, 'sash') + args)) or ()48374838def sash_coord(self, index):4839"""Return the current x and y pair for the sash given by index.48404841Index must be an integer between 0 and 1 less than the4842number of panes in the panedwindow. The coordinates given are4843those of the top left corner of the region containing the sash.4844pathName sash dragto index x y This command computes the4845difference between the given coordinates and the coordinates4846given to the last sash coord command for the given sash. It then4847moves that sash the computed difference. The return value is the4848empty string.4849"""4850return self.sash("coord", index)48514852def sash_mark(self, index):4853"""Records x and y for the sash given by index;48544855Used in conjunction with later dragto commands to move the sash.4856"""4857return self.sash("mark", index)48584859def sash_place(self, index, x, y):4860"""Place the sash given by index at the given coordinates4861"""4862return self.sash("place", index, x, y)48634864def panecget(self, child, option):4865"""Query a management option for window.48664867Option may be any value allowed by the paneconfigure subcommand4868"""4869return self.tk.call(4870(self._w, 'panecget') + (child, '-'+option))48714872def paneconfigure(self, tagOrId, cnf=None, **kw):4873"""Query or modify the management options for window.48744875If no option is specified, returns a list describing all4876of the available options for pathName. If option is4877specified with no value, then the command returns a list4878describing the one named option (this list will be identical4879to the corresponding sublist of the value returned if no4880option is specified). If one or more option-value pairs are4881specified, then the command modifies the given widget4882option(s) to have the given value(s); in this case the4883command returns an empty string. The following options4884are supported:48854886after window4887Insert the window after the window specified. window4888should be the name of a window already managed by pathName.4889before window4890Insert the window before the window specified. window4891should be the name of a window already managed by pathName.4892height size4893Specify a height for the window. The height will be the4894outer dimension of the window including its border, if4895any. If size is an empty string, or if -height is not4896specified, then the height requested internally by the4897window will be used initially; the height may later be4898adjusted by the movement of sashes in the panedwindow.4899Size may be any value accepted by Tk_GetPixels.4900minsize n4901Specifies that the size of the window cannot be made4902less than n. This constraint only affects the size of4903the widget in the paned dimension -- the x dimension4904for horizontal panedwindows, the y dimension for4905vertical panedwindows. May be any value accepted by4906Tk_GetPixels.4907padx n4908Specifies a non-negative value indicating how much4909extra space to leave on each side of the window in4910the X-direction. The value may have any of the forms4911accepted by Tk_GetPixels.4912pady n4913Specifies a non-negative value indicating how much4914extra space to leave on each side of the window in4915the Y-direction. The value may have any of the forms4916accepted by Tk_GetPixels.4917sticky style4918If a window's pane is larger than the requested4919dimensions of the window, this option may be used4920to position (or stretch) the window within its pane.4921Style is a string that contains zero or more of the4922characters n, s, e or w. The string can optionally4923contains spaces or commas, but they are ignored. Each4924letter refers to a side (north, south, east, or west)4925that the window will "stick" to. If both n and s4926(or e and w) are specified, the window will be4927stretched to fill the entire height (or width) of4928its cavity.4929width size4930Specify a width for the window. The width will be4931the outer dimension of the window including its4932border, if any. If size is an empty string, or4933if -width is not specified, then the width requested4934internally by the window will be used initially; the4935width may later be adjusted by the movement of sashes4936in the panedwindow. Size may be any value accepted by4937Tk_GetPixels.49384939"""4940if cnf is None and not kw:4941return self._getconfigure(self._w, 'paneconfigure', tagOrId)4942if isinstance(cnf, str) and not kw:4943return self._getconfigure1(4944self._w, 'paneconfigure', tagOrId, '-'+cnf)4945self.tk.call((self._w, 'paneconfigure', tagOrId) +4946self._options(cnf, kw))49474948paneconfig = paneconfigure49494950def panes(self):4951"""Returns an ordered list of the child panes."""4952return self.tk.splitlist(self.tk.call(self._w, 'panes'))49534954# Test:495549564957def _test():4958root = Tk()4959text = "This is Tcl/Tk %s" % root.globalgetvar('tk_patchLevel')4960text += "\nThis should be a cedilla: \xe7"4961label = Label(root, text=text)4962label.pack()4963test = Button(root, text="Click me!",4964command=lambda root=root: root.test.configure(4965text="[%s]" % root.test['text']))4966test.pack()4967root.test = test4968quit = Button(root, text="QUIT", command=root.destroy)4969quit.pack()4970# The following three commands are needed so the window pops4971# up on top on Windows...4972root.iconify()4973root.update()4974root.deiconify()4975root.mainloop()497649774978__all__ = [name for name, obj in globals().items()4979if not name.startswith('_') and not isinstance(obj, types.ModuleType)4980and name not in {'wantobjects'}]49814982if __name__ == '__main__':4983_test()498449854986