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