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