blob: e825afa0c11b1754d1ef05a68ac2cc878bcff1b7 [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()
Martin Panterf2f1c572016-05-08 13:18:25 +00001247 # serial field: valid for all events
Georg Brandl33cece02008-05-20 06:58:21 +00001248 # 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
Martin Panter4f23cab2016-05-08 13:45:55 +00001255 # x field: "valid for events that contain an x field"
Georg Brandl33cece02008-05-20 06:58:21 +00001256 # 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,
Martin Panterf2f1c572016-05-08 13:18:25 +00001259 # KeyRelease, and Motion events
Georg Brandl33cece02008-05-20 06:58:21 +00001260 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 Storchaka0fd213c2016-03-09 10:51:41 +02001338 splitlist = self.tk.splitlist
1339 return [splitlist(x)[0][1:] for x in
1340 splitlist(self.tk.call(self._w, 'configure'))]
Georg Brandl33cece02008-05-20 06:58:21 +00001341 def __str__(self):
1342 """Return the window path name of this widget."""
1343 return self._w
1344 # Pack methods that apply to the master
1345 _noarg_ = ['_noarg_']
1346 def pack_propagate(self, flag=_noarg_):
1347 """Set or get the status for propagation of geometry information.
1348
1349 A boolean argument specifies whether the geometry information
1350 of the slaves will determine the size of this widget. If no argument
1351 is given the current setting will be returned.
1352 """
1353 if flag is Misc._noarg_:
1354 return self._getboolean(self.tk.call(
1355 'pack', 'propagate', self._w))
1356 else:
1357 self.tk.call('pack', 'propagate', self._w, flag)
1358 propagate = pack_propagate
1359 def pack_slaves(self):
1360 """Return a list of all slaves of this widget
1361 in its packing order."""
1362 return map(self._nametowidget,
1363 self.tk.splitlist(
1364 self.tk.call('pack', 'slaves', self._w)))
1365 slaves = pack_slaves
1366 # Place method that applies to the master
1367 def place_slaves(self):
1368 """Return a list of all slaves of this widget
1369 in its packing order."""
1370 return map(self._nametowidget,
1371 self.tk.splitlist(
1372 self.tk.call(
1373 'place', 'slaves', self._w)))
1374 # Grid methods that apply to the master
1375 def grid_bbox(self, column=None, row=None, col2=None, row2=None):
1376 """Return a tuple of integer coordinates for the bounding
1377 box of this widget controlled by the geometry manager grid.
1378
1379 If COLUMN, ROW is given the bounding box applies from
1380 the cell with row and column 0 to the specified
1381 cell. If COL2 and ROW2 are given the bounding box
1382 starts at that cell.
1383
1384 The returned integers specify the offset of the upper left
1385 corner in the master widget and the width and height.
1386 """
1387 args = ('grid', 'bbox', self._w)
1388 if column is not None and row is not None:
1389 args = args + (column, row)
1390 if col2 is not None and row2 is not None:
1391 args = args + (col2, row2)
1392 return self._getints(self.tk.call(*args)) or None
1393
1394 bbox = grid_bbox
Serhiy Storchaka3e0cb092014-02-19 18:33:30 +02001395
1396 def _gridconvvalue(self, value):
1397 if isinstance(value, (str, _tkinter.Tcl_Obj)):
1398 try:
1399 svalue = str(value)
1400 if not svalue:
1401 return None
1402 elif '.' in svalue:
1403 return getdouble(svalue)
1404 else:
1405 return getint(svalue)
1406 except ValueError:
1407 pass
1408 return value
1409
Georg Brandl33cece02008-05-20 06:58:21 +00001410 def _grid_configure(self, command, index, cnf, kw):
1411 """Internal function."""
1412 if type(cnf) is StringType and not kw:
1413 if cnf[-1:] == '_':
1414 cnf = cnf[:-1]
1415 if cnf[:1] != '-':
1416 cnf = '-'+cnf
1417 options = (cnf,)
1418 else:
1419 options = self._options(cnf, kw)
1420 if not options:
Serhiy Storchakaceaf6822014-09-06 22:47:02 +03001421 return _splitdict(
1422 self.tk,
1423 self.tk.call('grid', command, self._w, index),
1424 conv=self._gridconvvalue)
Georg Brandl33cece02008-05-20 06:58:21 +00001425 res = self.tk.call(
1426 ('grid', command, self._w, index)
1427 + options)
1428 if len(options) == 1:
Serhiy Storchaka3e0cb092014-02-19 18:33:30 +02001429 return self._gridconvvalue(res)
1430
Georg Brandl33cece02008-05-20 06:58:21 +00001431 def grid_columnconfigure(self, index, cnf={}, **kw):
1432 """Configure column INDEX of a grid.
1433
1434 Valid resources are minsize (minimum size of the column),
1435 weight (how much does additional space propagate to this column)
1436 and pad (how much space to let additionally)."""
1437 return self._grid_configure('columnconfigure', index, cnf, kw)
1438 columnconfigure = grid_columnconfigure
1439 def grid_location(self, x, y):
1440 """Return a tuple of column and row which identify the cell
1441 at which the pixel at position X and Y inside the master
1442 widget is located."""
1443 return self._getints(
1444 self.tk.call(
1445 'grid', 'location', self._w, x, y)) or None
1446 def grid_propagate(self, flag=_noarg_):
1447 """Set or get the status for propagation of geometry information.
1448
1449 A boolean argument specifies whether the geometry information
1450 of the slaves will determine the size of this widget. If no argument
1451 is given, the current setting will be returned.
1452 """
1453 if flag is Misc._noarg_:
1454 return self._getboolean(self.tk.call(
1455 'grid', 'propagate', self._w))
1456 else:
1457 self.tk.call('grid', 'propagate', self._w, flag)
1458 def grid_rowconfigure(self, index, cnf={}, **kw):
1459 """Configure row INDEX of a grid.
1460
1461 Valid resources are minsize (minimum size of the row),
1462 weight (how much does additional space propagate to this row)
1463 and pad (how much space to let additionally)."""
1464 return self._grid_configure('rowconfigure', index, cnf, kw)
1465 rowconfigure = grid_rowconfigure
1466 def grid_size(self):
1467 """Return a tuple of the number of column and rows in the grid."""
1468 return self._getints(
1469 self.tk.call('grid', 'size', self._w)) or None
1470 size = grid_size
1471 def grid_slaves(self, row=None, column=None):
1472 """Return a list of all slaves of this widget
1473 in its packing order."""
1474 args = ()
1475 if row is not None:
1476 args = args + ('-row', row)
1477 if column is not None:
1478 args = args + ('-column', column)
1479 return map(self._nametowidget,
1480 self.tk.splitlist(self.tk.call(
1481 ('grid', 'slaves', self._w) + args)))
1482
1483 # Support for the "event" command, new in Tk 4.2.
1484 # By Case Roole.
1485
1486 def event_add(self, virtual, *sequences):
1487 """Bind a virtual event VIRTUAL (of the form <<Name>>)
1488 to an event SEQUENCE such that the virtual event is triggered
1489 whenever SEQUENCE occurs."""
1490 args = ('event', 'add', virtual) + sequences
1491 self.tk.call(args)
1492
1493 def event_delete(self, virtual, *sequences):
1494 """Unbind a virtual event VIRTUAL from SEQUENCE."""
1495 args = ('event', 'delete', virtual) + sequences
1496 self.tk.call(args)
1497
1498 def event_generate(self, sequence, **kw):
1499 """Generate an event SEQUENCE. Additional
1500 keyword arguments specify parameter of the event
1501 (e.g. x, y, rootx, rooty)."""
1502 args = ('event', 'generate', self._w, sequence)
1503 for k, v in kw.items():
1504 args = args + ('-%s' % k, str(v))
1505 self.tk.call(args)
1506
1507 def event_info(self, virtual=None):
1508 """Return a list of all virtual events or the information
1509 about the SEQUENCE bound to the virtual event VIRTUAL."""
1510 return self.tk.splitlist(
1511 self.tk.call('event', 'info', virtual))
1512
1513 # Image related commands
1514
1515 def image_names(self):
1516 """Return a list of all existing image names."""
Serhiy Storchaka9be238d2014-01-07 19:32:58 +02001517 return self.tk.splitlist(self.tk.call('image', 'names'))
Georg Brandl33cece02008-05-20 06:58:21 +00001518
1519 def image_types(self):
1520 """Return a list of all available image types (e.g. phote bitmap)."""
Serhiy Storchaka9be238d2014-01-07 19:32:58 +02001521 return self.tk.splitlist(self.tk.call('image', 'types'))
Georg Brandl33cece02008-05-20 06:58:21 +00001522
1523
1524class CallWrapper:
1525 """Internal class. Stores function to call when some user
1526 defined Tcl function is called e.g. after an event occurred."""
1527 def __init__(self, func, subst, widget):
1528 """Store FUNC, SUBST and WIDGET as members."""
1529 self.func = func
1530 self.subst = subst
1531 self.widget = widget
1532 def __call__(self, *args):
1533 """Apply first function SUBST to arguments, than FUNC."""
1534 try:
1535 if self.subst:
1536 args = self.subst(*args)
1537 return self.func(*args)
1538 except SystemExit, msg:
1539 raise SystemExit, msg
1540 except:
1541 self.widget._report_exception()
1542
1543
Guilherme Poloe45f0172009-08-14 14:36:45 +00001544class XView:
1545 """Mix-in class for querying and changing the horizontal position
1546 of a widget's window."""
1547
1548 def xview(self, *args):
1549 """Query and change the horizontal position of the view."""
1550 res = self.tk.call(self._w, 'xview', *args)
1551 if not args:
1552 return self._getdoubles(res)
1553
1554 def xview_moveto(self, fraction):
1555 """Adjusts the view in the window so that FRACTION of the
1556 total width of the canvas is off-screen to the left."""
1557 self.tk.call(self._w, 'xview', 'moveto', fraction)
1558
1559 def xview_scroll(self, number, what):
1560 """Shift the x-view according to NUMBER which is measured in "units"
1561 or "pages" (WHAT)."""
1562 self.tk.call(self._w, 'xview', 'scroll', number, what)
1563
1564
1565class YView:
1566 """Mix-in class for querying and changing the vertical position
1567 of a widget's window."""
1568
1569 def yview(self, *args):
1570 """Query and change the vertical position of the view."""
1571 res = self.tk.call(self._w, 'yview', *args)
1572 if not args:
1573 return self._getdoubles(res)
1574
1575 def yview_moveto(self, fraction):
1576 """Adjusts the view in the window so that FRACTION of the
1577 total height of the canvas is off-screen to the top."""
1578 self.tk.call(self._w, 'yview', 'moveto', fraction)
1579
1580 def yview_scroll(self, number, what):
1581 """Shift the y-view according to NUMBER which is measured in
1582 "units" or "pages" (WHAT)."""
1583 self.tk.call(self._w, 'yview', 'scroll', number, what)
1584
1585
Georg Brandl33cece02008-05-20 06:58:21 +00001586class Wm:
1587 """Provides functions for the communication with the window manager."""
1588
1589 def wm_aspect(self,
1590 minNumer=None, minDenom=None,
1591 maxNumer=None, maxDenom=None):
1592 """Instruct the window manager to set the aspect ratio (width/height)
1593 of this widget to be between MINNUMER/MINDENOM and MAXNUMER/MAXDENOM. Return a tuple
1594 of the actual values if no argument is given."""
1595 return self._getints(
1596 self.tk.call('wm', 'aspect', self._w,
1597 minNumer, minDenom,
1598 maxNumer, maxDenom))
1599 aspect = wm_aspect
1600
1601 def wm_attributes(self, *args):
1602 """This subcommand returns or sets platform specific attributes
1603
1604 The first form returns a list of the platform specific flags and
1605 their values. The second form returns the value for the specific
1606 option. The third form sets one or more of the values. The values
1607 are as follows:
1608
1609 On Windows, -disabled gets or sets whether the window is in a
1610 disabled state. -toolwindow gets or sets the style of the window
1611 to toolwindow (as defined in the MSDN). -topmost gets or sets
1612 whether this is a topmost window (displays above all other
1613 windows).
1614
1615 On Macintosh, XXXXX
1616
1617 On Unix, there are currently no special attribute values.
1618 """
1619 args = ('wm', 'attributes', self._w) + args
1620 return self.tk.call(args)
1621 attributes=wm_attributes
1622
1623 def wm_client(self, name=None):
1624 """Store NAME in WM_CLIENT_MACHINE property of this widget. Return
1625 current value."""
1626 return self.tk.call('wm', 'client', self._w, name)
1627 client = wm_client
1628 def wm_colormapwindows(self, *wlist):
1629 """Store list of window names (WLIST) into WM_COLORMAPWINDOWS property
1630 of this widget. This list contains windows whose colormaps differ from their
1631 parents. Return current list of widgets if WLIST is empty."""
1632 if len(wlist) > 1:
1633 wlist = (wlist,) # Tk needs a list of windows here
1634 args = ('wm', 'colormapwindows', self._w) + wlist
Serhiy Storchaka9be238d2014-01-07 19:32:58 +02001635 if wlist:
1636 self.tk.call(args)
1637 else:
1638 return map(self._nametowidget, self.tk.splitlist(self.tk.call(args)))
Georg Brandl33cece02008-05-20 06:58:21 +00001639 colormapwindows = wm_colormapwindows
1640 def wm_command(self, value=None):
1641 """Store VALUE in WM_COMMAND property. It is the command
1642 which shall be used to invoke the application. Return current
1643 command if VALUE is None."""
1644 return self.tk.call('wm', 'command', self._w, value)
1645 command = wm_command
1646 def wm_deiconify(self):
1647 """Deiconify this widget. If it was never mapped it will not be mapped.
1648 On Windows it will raise this widget and give it the focus."""
1649 return self.tk.call('wm', 'deiconify', self._w)
1650 deiconify = wm_deiconify
1651 def wm_focusmodel(self, model=None):
1652 """Set focus model to MODEL. "active" means that this widget will claim
1653 the focus itself, "passive" means that the window manager shall give
1654 the focus. Return current focus model if MODEL is None."""
1655 return self.tk.call('wm', 'focusmodel', self._w, model)
1656 focusmodel = wm_focusmodel
1657 def wm_frame(self):
1658 """Return identifier for decorative frame of this widget if present."""
1659 return self.tk.call('wm', 'frame', self._w)
1660 frame = wm_frame
1661 def wm_geometry(self, newGeometry=None):
1662 """Set geometry to NEWGEOMETRY of the form =widthxheight+x+y. Return
1663 current value if None is given."""
1664 return self.tk.call('wm', 'geometry', self._w, newGeometry)
1665 geometry = wm_geometry
1666 def wm_grid(self,
1667 baseWidth=None, baseHeight=None,
1668 widthInc=None, heightInc=None):
1669 """Instruct the window manager that this widget shall only be
1670 resized on grid boundaries. WIDTHINC and HEIGHTINC are the width and
1671 height of a grid unit in pixels. BASEWIDTH and BASEHEIGHT are the
1672 number of grid units requested in Tk_GeometryRequest."""
1673 return self._getints(self.tk.call(
1674 'wm', 'grid', self._w,
1675 baseWidth, baseHeight, widthInc, heightInc))
1676 grid = wm_grid
1677 def wm_group(self, pathName=None):
1678 """Set the group leader widgets for related widgets to PATHNAME. Return
1679 the group leader of this widget if None is given."""
1680 return self.tk.call('wm', 'group', self._w, pathName)
1681 group = wm_group
1682 def wm_iconbitmap(self, bitmap=None, default=None):
1683 """Set bitmap for the iconified widget to BITMAP. Return
1684 the bitmap if None is given.
1685
1686 Under Windows, the DEFAULT parameter can be used to set the icon
1687 for the widget and any descendents that don't have an icon set
1688 explicitly. DEFAULT can be the relative path to a .ico file
1689 (example: root.iconbitmap(default='myicon.ico') ). See Tk
1690 documentation for more information."""
1691 if default:
1692 return self.tk.call('wm', 'iconbitmap', self._w, '-default', default)
1693 else:
1694 return self.tk.call('wm', 'iconbitmap', self._w, bitmap)
1695 iconbitmap = wm_iconbitmap
1696 def wm_iconify(self):
1697 """Display widget as icon."""
1698 return self.tk.call('wm', 'iconify', self._w)
1699 iconify = wm_iconify
1700 def wm_iconmask(self, bitmap=None):
1701 """Set mask for the icon bitmap of this widget. Return the
1702 mask if None is given."""
1703 return self.tk.call('wm', 'iconmask', self._w, bitmap)
1704 iconmask = wm_iconmask
1705 def wm_iconname(self, newName=None):
1706 """Set the name of the icon for this widget. Return the name if
1707 None is given."""
1708 return self.tk.call('wm', 'iconname', self._w, newName)
1709 iconname = wm_iconname
1710 def wm_iconposition(self, x=None, y=None):
1711 """Set the position of the icon of this widget to X and Y. Return
1712 a tuple of the current values of X and X if None is given."""
1713 return self._getints(self.tk.call(
1714 'wm', 'iconposition', self._w, x, y))
1715 iconposition = wm_iconposition
1716 def wm_iconwindow(self, pathName=None):
1717 """Set widget PATHNAME to be displayed instead of icon. Return the current
1718 value if None is given."""
1719 return self.tk.call('wm', 'iconwindow', self._w, pathName)
1720 iconwindow = wm_iconwindow
1721 def wm_maxsize(self, width=None, height=None):
1722 """Set max WIDTH and HEIGHT for this widget. If the window is gridded
1723 the values are given in grid units. Return the current values if None
1724 is given."""
1725 return self._getints(self.tk.call(
1726 'wm', 'maxsize', self._w, width, height))
1727 maxsize = wm_maxsize
1728 def wm_minsize(self, width=None, height=None):
1729 """Set min WIDTH and HEIGHT for this widget. If the window is gridded
1730 the values are given in grid units. Return the current values if None
1731 is given."""
1732 return self._getints(self.tk.call(
1733 'wm', 'minsize', self._w, width, height))
1734 minsize = wm_minsize
1735 def wm_overrideredirect(self, boolean=None):
1736 """Instruct the window manager to ignore this widget
1737 if BOOLEAN is given with 1. Return the current value if None
1738 is given."""
1739 return self._getboolean(self.tk.call(
1740 'wm', 'overrideredirect', self._w, boolean))
1741 overrideredirect = wm_overrideredirect
1742 def wm_positionfrom(self, who=None):
1743 """Instruct the window manager that the position of this widget shall
1744 be defined by the user if WHO is "user", and by its own policy if WHO is
1745 "program"."""
1746 return self.tk.call('wm', 'positionfrom', self._w, who)
1747 positionfrom = wm_positionfrom
1748 def wm_protocol(self, name=None, func=None):
1749 """Bind function FUNC to command NAME for this widget.
1750 Return the function bound to NAME if None is given. NAME could be
1751 e.g. "WM_SAVE_YOURSELF" or "WM_DELETE_WINDOW"."""
Brett Cannonff6868c2008-08-04 21:24:43 +00001752 if hasattr(func, '__call__'):
Georg Brandl33cece02008-05-20 06:58:21 +00001753 command = self._register(func)
1754 else:
1755 command = func
1756 return self.tk.call(
1757 'wm', 'protocol', self._w, name, command)
1758 protocol = wm_protocol
1759 def wm_resizable(self, width=None, height=None):
1760 """Instruct the window manager whether this width can be resized
1761 in WIDTH or HEIGHT. Both values are boolean values."""
1762 return self.tk.call('wm', 'resizable', self._w, width, height)
1763 resizable = wm_resizable
1764 def wm_sizefrom(self, who=None):
1765 """Instruct the window manager that the size of this widget shall
1766 be defined by the user if WHO is "user", and by its own policy if WHO is
1767 "program"."""
1768 return self.tk.call('wm', 'sizefrom', self._w, who)
1769 sizefrom = wm_sizefrom
1770 def wm_state(self, newstate=None):
1771 """Query or set the state of this widget as one of normal, icon,
1772 iconic (see wm_iconwindow), withdrawn, or zoomed (Windows only)."""
1773 return self.tk.call('wm', 'state', self._w, newstate)
1774 state = wm_state
1775 def wm_title(self, string=None):
1776 """Set the title of this widget."""
1777 return self.tk.call('wm', 'title', self._w, string)
1778 title = wm_title
1779 def wm_transient(self, master=None):
1780 """Instruct the window manager that this widget is transient
1781 with regard to widget MASTER."""
1782 return self.tk.call('wm', 'transient', self._w, master)
1783 transient = wm_transient
1784 def wm_withdraw(self):
1785 """Withdraw this widget from the screen such that it is unmapped
1786 and forgotten by the window manager. Re-draw it with wm_deiconify."""
1787 return self.tk.call('wm', 'withdraw', self._w)
1788 withdraw = wm_withdraw
1789
1790
1791class Tk(Misc, Wm):
1792 """Toplevel widget of Tk which represents mostly the main window
Ezio Melotti24b07bc2011-03-15 18:55:01 +02001793 of an application. It has an associated Tcl interpreter."""
Georg Brandl33cece02008-05-20 06:58:21 +00001794 _w = '.'
1795 def __init__(self, screenName=None, baseName=None, className='Tk',
1796 useTk=1, sync=0, use=None):
1797 """Return a new Toplevel widget on screen SCREENNAME. A new Tcl interpreter will
1798 be created. BASENAME will be used for the identification of the profile file (see
1799 readprofile).
1800 It is constructed from sys.argv[0] without extensions if None is given. CLASSNAME
1801 is the name of the widget class."""
1802 self.master = None
1803 self.children = {}
1804 self._tkloaded = 0
1805 # to avoid recursions in the getattr code in case of failure, we
1806 # ensure that self.tk is always _something_.
1807 self.tk = None
1808 if baseName is None:
Antoine Pitrouba7620c2013-08-01 22:25:12 +02001809 import os
Georg Brandl33cece02008-05-20 06:58:21 +00001810 baseName = os.path.basename(sys.argv[0])
1811 baseName, ext = os.path.splitext(baseName)
1812 if ext not in ('.py', '.pyc', '.pyo'):
1813 baseName = baseName + ext
1814 interactive = 0
1815 self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
1816 if useTk:
1817 self._loadtk()
Antoine Pitrou7dddec42012-12-09 14:46:18 +01001818 if not sys.flags.ignore_environment:
1819 # Issue #16248: Honor the -E flag to avoid code injection.
1820 self.readprofile(baseName, className)
Georg Brandl33cece02008-05-20 06:58:21 +00001821 def loadtk(self):
1822 if not self._tkloaded:
1823 self.tk.loadtk()
1824 self._loadtk()
1825 def _loadtk(self):
1826 self._tkloaded = 1
1827 global _default_root
Georg Brandl33cece02008-05-20 06:58:21 +00001828 # Version sanity checks
1829 tk_version = self.tk.getvar('tk_version')
1830 if tk_version != _tkinter.TK_VERSION:
1831 raise RuntimeError, \
1832 "tk.h version (%s) doesn't match libtk.a version (%s)" \
1833 % (_tkinter.TK_VERSION, tk_version)
1834 # Under unknown circumstances, tcl_version gets coerced to float
1835 tcl_version = str(self.tk.getvar('tcl_version'))
1836 if tcl_version != _tkinter.TCL_VERSION:
1837 raise RuntimeError, \
1838 "tcl.h version (%s) doesn't match libtcl.a version (%s)" \
1839 % (_tkinter.TCL_VERSION, tcl_version)
1840 if TkVersion < 4.0:
1841 raise RuntimeError, \
1842 "Tk 4.0 or higher is required; found Tk %s" \
1843 % str(TkVersion)
1844 # Create and register the tkerror and exit commands
1845 # We need to inline parts of _register here, _ register
1846 # would register differently-named commands.
1847 if self._tclCommands is None:
1848 self._tclCommands = []
1849 self.tk.createcommand('tkerror', _tkerror)
1850 self.tk.createcommand('exit', _exit)
1851 self._tclCommands.append('tkerror')
1852 self._tclCommands.append('exit')
1853 if _support_default_root and not _default_root:
1854 _default_root = self
1855 self.protocol("WM_DELETE_WINDOW", self.destroy)
1856 def destroy(self):
1857 """Destroy this and all descendants widgets. This will
1858 end the application of this Tcl interpreter."""
1859 for c in self.children.values(): c.destroy()
1860 self.tk.call('destroy', self._w)
1861 Misc.destroy(self)
1862 global _default_root
1863 if _support_default_root and _default_root is self:
1864 _default_root = None
1865 def readprofile(self, baseName, className):
1866 """Internal function. It reads BASENAME.tcl and CLASSNAME.tcl into
1867 the Tcl Interpreter and calls execfile on BASENAME.py and CLASSNAME.py if
1868 such a file exists in the home directory."""
1869 import os
Benjamin Peterson6e3dbbd2009-10-09 22:15:50 +00001870 if 'HOME' in os.environ: home = os.environ['HOME']
Georg Brandl33cece02008-05-20 06:58:21 +00001871 else: home = os.curdir
1872 class_tcl = os.path.join(home, '.%s.tcl' % className)
1873 class_py = os.path.join(home, '.%s.py' % className)
1874 base_tcl = os.path.join(home, '.%s.tcl' % baseName)
1875 base_py = os.path.join(home, '.%s.py' % baseName)
1876 dir = {'self': self}
Georg Brandl6634bf22008-05-20 07:13:37 +00001877 exec 'from Tkinter import *' in dir
Georg Brandl33cece02008-05-20 06:58:21 +00001878 if os.path.isfile(class_tcl):
1879 self.tk.call('source', class_tcl)
1880 if os.path.isfile(class_py):
1881 execfile(class_py, dir)
1882 if os.path.isfile(base_tcl):
1883 self.tk.call('source', base_tcl)
1884 if os.path.isfile(base_py):
1885 execfile(base_py, dir)
1886 def report_callback_exception(self, exc, val, tb):
Serhiy Storchaka2971c5e2014-09-14 21:17:16 +03001887 """Report callback exception on sys.stderr.
1888
1889 Applications may want to override this internal function, and
1890 should when sys.stderr is None."""
Georg Brandl33cece02008-05-20 06:58:21 +00001891 import traceback, sys
Serhiy Storchaka2971c5e2014-09-14 21:17:16 +03001892 print >>sys.stderr, "Exception in Tkinter callback"
Georg Brandl33cece02008-05-20 06:58:21 +00001893 sys.last_type = exc
1894 sys.last_value = val
1895 sys.last_traceback = tb
1896 traceback.print_exception(exc, val, tb)
1897 def __getattr__(self, attr):
1898 "Delegate attribute access to the interpreter object"
1899 return getattr(self.tk, attr)
1900
1901# Ideally, the classes Pack, Place and Grid disappear, the
1902# pack/place/grid methods are defined on the Widget class, and
1903# everybody uses w.pack_whatever(...) instead of Pack.whatever(w,
1904# ...), with pack(), place() and grid() being short for
1905# pack_configure(), place_configure() and grid_columnconfigure(), and
1906# forget() being short for pack_forget(). As a practical matter, I'm
1907# afraid that there is too much code out there that may be using the
1908# Pack, Place or Grid class, so I leave them intact -- but only as
1909# backwards compatibility features. Also note that those methods that
1910# take a master as argument (e.g. pack_propagate) have been moved to
1911# the Misc class (which now incorporates all methods common between
1912# toplevel and interior widgets). Again, for compatibility, these are
1913# copied into the Pack, Place or Grid class.
1914
1915
1916def Tcl(screenName=None, baseName=None, className='Tk', useTk=0):
1917 return Tk(screenName, baseName, className, useTk)
1918
1919class Pack:
1920 """Geometry manager Pack.
1921
1922 Base class to use the methods pack_* in every widget."""
1923 def pack_configure(self, cnf={}, **kw):
1924 """Pack a widget in the parent widget. Use as options:
1925 after=widget - pack it after you have packed widget
1926 anchor=NSEW (or subset) - position widget according to
1927 given direction
Georg Brandl7943a322008-05-29 07:18:49 +00001928 before=widget - pack it before you will pack widget
Georg Brandl33cece02008-05-20 06:58:21 +00001929 expand=bool - expand widget if parent size grows
1930 fill=NONE or X or Y or BOTH - fill widget if widget grows
1931 in=master - use master to contain this widget
Georg Brandl7943a322008-05-29 07:18:49 +00001932 in_=master - see 'in' option description
Georg Brandl33cece02008-05-20 06:58:21 +00001933 ipadx=amount - add internal padding in x direction
1934 ipady=amount - add internal padding in y direction
1935 padx=amount - add padding in x direction
1936 pady=amount - add padding in y direction
1937 side=TOP or BOTTOM or LEFT or RIGHT - where to add this widget.
1938 """
1939 self.tk.call(
1940 ('pack', 'configure', self._w)
1941 + self._options(cnf, kw))
1942 pack = configure = config = pack_configure
1943 def pack_forget(self):
1944 """Unmap this widget and do not use it for the packing order."""
1945 self.tk.call('pack', 'forget', self._w)
1946 forget = pack_forget
1947 def pack_info(self):
1948 """Return information about the packing options
1949 for this widget."""
Serhiy Storchakaceaf6822014-09-06 22:47:02 +03001950 d = _splitdict(self.tk, self.tk.call('pack', 'info', self._w))
1951 if 'in' in d:
1952 d['in'] = self.nametowidget(d['in'])
1953 return d
Georg Brandl33cece02008-05-20 06:58:21 +00001954 info = pack_info
1955 propagate = pack_propagate = Misc.pack_propagate
1956 slaves = pack_slaves = Misc.pack_slaves
1957
1958class Place:
1959 """Geometry manager Place.
1960
1961 Base class to use the methods place_* in every widget."""
1962 def place_configure(self, cnf={}, **kw):
1963 """Place a widget in the parent widget. Use as options:
Georg Brandl7943a322008-05-29 07:18:49 +00001964 in=master - master relative to which the widget is placed
1965 in_=master - see 'in' option description
Georg Brandl33cece02008-05-20 06:58:21 +00001966 x=amount - locate anchor of this widget at position x of master
1967 y=amount - locate anchor of this widget at position y of master
1968 relx=amount - locate anchor of this widget between 0.0 and 1.0
1969 relative to width of master (1.0 is right edge)
Georg Brandl7943a322008-05-29 07:18:49 +00001970 rely=amount - locate anchor of this widget between 0.0 and 1.0
Georg Brandl33cece02008-05-20 06:58:21 +00001971 relative to height of master (1.0 is bottom edge)
Georg Brandl7943a322008-05-29 07:18:49 +00001972 anchor=NSEW (or subset) - position anchor according to given direction
Georg Brandl33cece02008-05-20 06:58:21 +00001973 width=amount - width of this widget in pixel
1974 height=amount - height of this widget in pixel
1975 relwidth=amount - width of this widget between 0.0 and 1.0
1976 relative to width of master (1.0 is the same width
Georg Brandl7943a322008-05-29 07:18:49 +00001977 as the master)
1978 relheight=amount - height of this widget between 0.0 and 1.0
Georg Brandl33cece02008-05-20 06:58:21 +00001979 relative to height of master (1.0 is the same
Georg Brandl7943a322008-05-29 07:18:49 +00001980 height as the master)
1981 bordermode="inside" or "outside" - whether to take border width of
1982 master widget into account
1983 """
Georg Brandl33cece02008-05-20 06:58:21 +00001984 self.tk.call(
1985 ('place', 'configure', self._w)
1986 + self._options(cnf, kw))
1987 place = configure = config = place_configure
1988 def place_forget(self):
1989 """Unmap this widget."""
1990 self.tk.call('place', 'forget', self._w)
1991 forget = place_forget
1992 def place_info(self):
1993 """Return information about the placing options
1994 for this widget."""
Serhiy Storchakaceaf6822014-09-06 22:47:02 +03001995 d = _splitdict(self.tk, self.tk.call('place', 'info', self._w))
1996 if 'in' in d:
1997 d['in'] = self.nametowidget(d['in'])
1998 return d
Georg Brandl33cece02008-05-20 06:58:21 +00001999 info = place_info
2000 slaves = place_slaves = Misc.place_slaves
2001
2002class Grid:
2003 """Geometry manager Grid.
2004
2005 Base class to use the methods grid_* in every widget."""
2006 # Thanks to Masazumi Yoshikawa (yosikawa@isi.edu)
2007 def grid_configure(self, cnf={}, **kw):
2008 """Position a widget in the parent widget in a grid. Use as options:
2009 column=number - use cell identified with given column (starting with 0)
2010 columnspan=number - this widget will span several columns
2011 in=master - use master to contain this widget
Georg Brandl7943a322008-05-29 07:18:49 +00002012 in_=master - see 'in' option description
Georg Brandl33cece02008-05-20 06:58:21 +00002013 ipadx=amount - add internal padding in x direction
2014 ipady=amount - add internal padding in y direction
2015 padx=amount - add padding in x direction
2016 pady=amount - add padding in y direction
2017 row=number - use cell identified with given row (starting with 0)
2018 rowspan=number - this widget will span several rows
2019 sticky=NSEW - if cell is larger on which sides will this
2020 widget stick to the cell boundary
2021 """
2022 self.tk.call(
2023 ('grid', 'configure', self._w)
2024 + self._options(cnf, kw))
2025 grid = configure = config = grid_configure
2026 bbox = grid_bbox = Misc.grid_bbox
2027 columnconfigure = grid_columnconfigure = Misc.grid_columnconfigure
2028 def grid_forget(self):
2029 """Unmap this widget."""
2030 self.tk.call('grid', 'forget', self._w)
2031 forget = grid_forget
2032 def grid_remove(self):
2033 """Unmap this widget but remember the grid options."""
2034 self.tk.call('grid', 'remove', self._w)
2035 def grid_info(self):
2036 """Return information about the options
2037 for positioning this widget in a grid."""
Serhiy Storchakaceaf6822014-09-06 22:47:02 +03002038 d = _splitdict(self.tk, self.tk.call('grid', 'info', self._w))
2039 if 'in' in d:
2040 d['in'] = self.nametowidget(d['in'])
2041 return d
Georg Brandl33cece02008-05-20 06:58:21 +00002042 info = grid_info
2043 location = grid_location = Misc.grid_location
2044 propagate = grid_propagate = Misc.grid_propagate
2045 rowconfigure = grid_rowconfigure = Misc.grid_rowconfigure
2046 size = grid_size = Misc.grid_size
2047 slaves = grid_slaves = Misc.grid_slaves
2048
2049class BaseWidget(Misc):
2050 """Internal class."""
2051 def _setup(self, master, cnf):
2052 """Internal function. Sets up information about children."""
2053 if _support_default_root:
2054 global _default_root
2055 if not master:
2056 if not _default_root:
2057 _default_root = Tk()
2058 master = _default_root
2059 self.master = master
2060 self.tk = master.tk
2061 name = None
Benjamin Peterson6e3dbbd2009-10-09 22:15:50 +00002062 if 'name' in cnf:
Georg Brandl33cece02008-05-20 06:58:21 +00002063 name = cnf['name']
2064 del cnf['name']
2065 if not name:
2066 name = repr(id(self))
2067 self._name = name
2068 if master._w=='.':
2069 self._w = '.' + name
2070 else:
2071 self._w = master._w + '.' + name
2072 self.children = {}
Benjamin Peterson6e3dbbd2009-10-09 22:15:50 +00002073 if self._name in self.master.children:
Georg Brandl33cece02008-05-20 06:58:21 +00002074 self.master.children[self._name].destroy()
2075 self.master.children[self._name] = self
2076 def __init__(self, master, widgetName, cnf={}, kw={}, extra=()):
2077 """Construct a widget with the parent widget MASTER, a name WIDGETNAME
2078 and appropriate options."""
2079 if kw:
2080 cnf = _cnfmerge((cnf, kw))
2081 self.widgetName = widgetName
2082 BaseWidget._setup(self, master, cnf)
Hirokazu Yamamotob9828f62008-11-03 18:03:06 +00002083 if self._tclCommands is None:
2084 self._tclCommands = []
Georg Brandl33cece02008-05-20 06:58:21 +00002085 classes = []
2086 for k in cnf.keys():
2087 if type(k) is ClassType:
2088 classes.append((k, cnf[k]))
2089 del cnf[k]
2090 self.tk.call(
2091 (widgetName, self._w) + extra + self._options(cnf))
2092 for k, v in classes:
2093 k.configure(self, v)
2094 def destroy(self):
2095 """Destroy this and all descendants widgets."""
2096 for c in self.children.values(): c.destroy()
2097 self.tk.call('destroy', self._w)
Benjamin Peterson6e3dbbd2009-10-09 22:15:50 +00002098 if self._name in self.master.children:
Georg Brandl33cece02008-05-20 06:58:21 +00002099 del self.master.children[self._name]
2100 Misc.destroy(self)
2101 def _do(self, name, args=()):
2102 # XXX Obsolete -- better use self.tk.call directly!
2103 return self.tk.call((self._w, name) + args)
2104
2105class Widget(BaseWidget, Pack, Place, Grid):
2106 """Internal class.
2107
2108 Base class for a widget which can be positioned with the geometry managers
2109 Pack, Place or Grid."""
2110 pass
2111
2112class Toplevel(BaseWidget, Wm):
2113 """Toplevel widget, e.g. for dialogs."""
2114 def __init__(self, master=None, cnf={}, **kw):
2115 """Construct a toplevel widget with the parent MASTER.
2116
2117 Valid resource names: background, bd, bg, borderwidth, class,
2118 colormap, container, cursor, height, highlightbackground,
2119 highlightcolor, highlightthickness, menu, relief, screen, takefocus,
2120 use, visual, width."""
2121 if kw:
2122 cnf = _cnfmerge((cnf, kw))
2123 extra = ()
2124 for wmkey in ['screen', 'class_', 'class', 'visual',
2125 'colormap']:
Benjamin Peterson6e3dbbd2009-10-09 22:15:50 +00002126 if wmkey in cnf:
Georg Brandl33cece02008-05-20 06:58:21 +00002127 val = cnf[wmkey]
2128 # TBD: a hack needed because some keys
2129 # are not valid as keyword arguments
2130 if wmkey[-1] == '_': opt = '-'+wmkey[:-1]
2131 else: opt = '-'+wmkey
2132 extra = extra + (opt, val)
2133 del cnf[wmkey]
2134 BaseWidget.__init__(self, master, 'toplevel', cnf, {}, extra)
2135 root = self._root()
2136 self.iconname(root.iconname())
2137 self.title(root.title())
2138 self.protocol("WM_DELETE_WINDOW", self.destroy)
2139
2140class Button(Widget):
2141 """Button widget."""
2142 def __init__(self, master=None, cnf={}, **kw):
2143 """Construct a button widget with the parent MASTER.
2144
2145 STANDARD OPTIONS
2146
2147 activebackground, activeforeground, anchor,
2148 background, bitmap, borderwidth, cursor,
2149 disabledforeground, font, foreground
2150 highlightbackground, highlightcolor,
2151 highlightthickness, image, justify,
2152 padx, pady, relief, repeatdelay,
2153 repeatinterval, takefocus, text,
2154 textvariable, underline, wraplength
2155
2156 WIDGET-SPECIFIC OPTIONS
2157
2158 command, compound, default, height,
2159 overrelief, state, width
2160 """
2161 Widget.__init__(self, master, 'button', cnf, kw)
2162
2163 def tkButtonEnter(self, *dummy):
2164 self.tk.call('tkButtonEnter', self._w)
2165
2166 def tkButtonLeave(self, *dummy):
2167 self.tk.call('tkButtonLeave', self._w)
2168
2169 def tkButtonDown(self, *dummy):
2170 self.tk.call('tkButtonDown', self._w)
2171
2172 def tkButtonUp(self, *dummy):
2173 self.tk.call('tkButtonUp', self._w)
2174
2175 def tkButtonInvoke(self, *dummy):
2176 self.tk.call('tkButtonInvoke', self._w)
2177
2178 def flash(self):
2179 """Flash the button.
2180
2181 This is accomplished by redisplaying
2182 the button several times, alternating between active and
2183 normal colors. At the end of the flash the button is left
2184 in the same normal/active state as when the command was
2185 invoked. This command is ignored if the button's state is
2186 disabled.
2187 """
2188 self.tk.call(self._w, 'flash')
2189
2190 def invoke(self):
2191 """Invoke the command associated with the button.
2192
2193 The return value is the return value from the command,
2194 or an empty string if there is no command associated with
2195 the button. This command is ignored if the button's state
2196 is disabled.
2197 """
2198 return self.tk.call(self._w, 'invoke')
2199
2200# Indices:
2201# XXX I don't like these -- take them away
2202def AtEnd():
2203 return 'end'
2204def AtInsert(*args):
2205 s = 'insert'
2206 for a in args:
2207 if a: s = s + (' ' + a)
2208 return s
2209def AtSelFirst():
2210 return 'sel.first'
2211def AtSelLast():
2212 return 'sel.last'
2213def At(x, y=None):
2214 if y is None:
2215 return '@%r' % (x,)
2216 else:
2217 return '@%r,%r' % (x, y)
2218
Guilherme Poloe45f0172009-08-14 14:36:45 +00002219class Canvas(Widget, XView, YView):
Georg Brandl33cece02008-05-20 06:58:21 +00002220 """Canvas widget to display graphical elements like lines or text."""
2221 def __init__(self, master=None, cnf={}, **kw):
2222 """Construct a canvas widget with the parent MASTER.
2223
2224 Valid resource names: background, bd, bg, borderwidth, closeenough,
2225 confine, cursor, height, highlightbackground, highlightcolor,
2226 highlightthickness, insertbackground, insertborderwidth,
2227 insertofftime, insertontime, insertwidth, offset, relief,
2228 scrollregion, selectbackground, selectborderwidth, selectforeground,
2229 state, takefocus, width, xscrollcommand, xscrollincrement,
2230 yscrollcommand, yscrollincrement."""
2231 Widget.__init__(self, master, 'canvas', cnf, kw)
2232 def addtag(self, *args):
2233 """Internal function."""
2234 self.tk.call((self._w, 'addtag') + args)
2235 def addtag_above(self, newtag, tagOrId):
2236 """Add tag NEWTAG to all items above TAGORID."""
2237 self.addtag(newtag, 'above', tagOrId)
2238 def addtag_all(self, newtag):
2239 """Add tag NEWTAG to all items."""
2240 self.addtag(newtag, 'all')
2241 def addtag_below(self, newtag, tagOrId):
2242 """Add tag NEWTAG to all items below TAGORID."""
2243 self.addtag(newtag, 'below', tagOrId)
2244 def addtag_closest(self, newtag, x, y, halo=None, start=None):
2245 """Add tag NEWTAG to item which is closest to pixel at X, Y.
2246 If several match take the top-most.
2247 All items closer than HALO are considered overlapping (all are
2248 closests). If START is specified the next below this tag is taken."""
2249 self.addtag(newtag, 'closest', x, y, halo, start)
2250 def addtag_enclosed(self, newtag, x1, y1, x2, y2):
2251 """Add tag NEWTAG to all items in the rectangle defined
2252 by X1,Y1,X2,Y2."""
2253 self.addtag(newtag, 'enclosed', x1, y1, x2, y2)
2254 def addtag_overlapping(self, newtag, x1, y1, x2, y2):
2255 """Add tag NEWTAG to all items which overlap the rectangle
2256 defined by X1,Y1,X2,Y2."""
2257 self.addtag(newtag, 'overlapping', x1, y1, x2, y2)
2258 def addtag_withtag(self, newtag, tagOrId):
2259 """Add tag NEWTAG to all items with TAGORID."""
2260 self.addtag(newtag, 'withtag', tagOrId)
2261 def bbox(self, *args):
2262 """Return a tuple of X1,Y1,X2,Y2 coordinates for a rectangle
2263 which encloses all items with tags specified as arguments."""
2264 return self._getints(
2265 self.tk.call((self._w, 'bbox') + args)) or None
2266 def tag_unbind(self, tagOrId, sequence, funcid=None):
2267 """Unbind for all items with TAGORID for event SEQUENCE the
2268 function identified with FUNCID."""
2269 self.tk.call(self._w, 'bind', tagOrId, sequence, '')
2270 if funcid:
2271 self.deletecommand(funcid)
2272 def tag_bind(self, tagOrId, sequence=None, func=None, add=None):
2273 """Bind to all items with TAGORID at event SEQUENCE a call to function FUNC.
2274
2275 An additional boolean parameter ADD specifies whether FUNC will be
2276 called additionally to the other bound function or whether it will
2277 replace the previous function. See bind for the return value."""
2278 return self._bind((self._w, 'bind', tagOrId),
2279 sequence, func, add)
2280 def canvasx(self, screenx, gridspacing=None):
2281 """Return the canvas x coordinate of pixel position SCREENX rounded
2282 to nearest multiple of GRIDSPACING units."""
2283 return getdouble(self.tk.call(
2284 self._w, 'canvasx', screenx, gridspacing))
2285 def canvasy(self, screeny, gridspacing=None):
2286 """Return the canvas y coordinate of pixel position SCREENY rounded
2287 to nearest multiple of GRIDSPACING units."""
2288 return getdouble(self.tk.call(
2289 self._w, 'canvasy', screeny, gridspacing))
2290 def coords(self, *args):
2291 """Return a list of coordinates for the item given in ARGS."""
2292 # XXX Should use _flatten on args
2293 return map(getdouble,
2294 self.tk.splitlist(
2295 self.tk.call((self._w, 'coords') + args)))
2296 def _create(self, itemType, args, kw): # Args: (val, val, ..., cnf={})
2297 """Internal function."""
2298 args = _flatten(args)
2299 cnf = args[-1]
2300 if type(cnf) in (DictionaryType, TupleType):
2301 args = args[:-1]
2302 else:
2303 cnf = {}
2304 return getint(self.tk.call(
2305 self._w, 'create', itemType,
2306 *(args + self._options(cnf, kw))))
2307 def create_arc(self, *args, **kw):
2308 """Create arc shaped region with coordinates x1,y1,x2,y2."""
2309 return self._create('arc', args, kw)
2310 def create_bitmap(self, *args, **kw):
2311 """Create bitmap with coordinates x1,y1."""
2312 return self._create('bitmap', args, kw)
2313 def create_image(self, *args, **kw):
2314 """Create image item with coordinates x1,y1."""
2315 return self._create('image', args, kw)
2316 def create_line(self, *args, **kw):
2317 """Create line with coordinates x1,y1,...,xn,yn."""
2318 return self._create('line', args, kw)
2319 def create_oval(self, *args, **kw):
2320 """Create oval with coordinates x1,y1,x2,y2."""
2321 return self._create('oval', args, kw)
2322 def create_polygon(self, *args, **kw):
2323 """Create polygon with coordinates x1,y1,...,xn,yn."""
2324 return self._create('polygon', args, kw)
2325 def create_rectangle(self, *args, **kw):
2326 """Create rectangle with coordinates x1,y1,x2,y2."""
2327 return self._create('rectangle', args, kw)
2328 def create_text(self, *args, **kw):
2329 """Create text with coordinates x1,y1."""
2330 return self._create('text', args, kw)
2331 def create_window(self, *args, **kw):
2332 """Create window with coordinates x1,y1,x2,y2."""
2333 return self._create('window', args, kw)
2334 def dchars(self, *args):
2335 """Delete characters of text items identified by tag or id in ARGS (possibly
2336 several times) from FIRST to LAST character (including)."""
2337 self.tk.call((self._w, 'dchars') + args)
2338 def delete(self, *args):
2339 """Delete items identified by all tag or ids contained in ARGS."""
2340 self.tk.call((self._w, 'delete') + args)
2341 def dtag(self, *args):
2342 """Delete tag or id given as last arguments in ARGS from items
2343 identified by first argument in ARGS."""
2344 self.tk.call((self._w, 'dtag') + args)
2345 def find(self, *args):
2346 """Internal function."""
2347 return self._getints(
2348 self.tk.call((self._w, 'find') + args)) or ()
2349 def find_above(self, tagOrId):
2350 """Return items above TAGORID."""
2351 return self.find('above', tagOrId)
2352 def find_all(self):
2353 """Return all items."""
2354 return self.find('all')
2355 def find_below(self, tagOrId):
2356 """Return all items below TAGORID."""
2357 return self.find('below', tagOrId)
2358 def find_closest(self, x, y, halo=None, start=None):
2359 """Return item which is closest to pixel at X, Y.
2360 If several match take the top-most.
2361 All items closer than HALO are considered overlapping (all are
2362 closests). If START is specified the next below this tag is taken."""
2363 return self.find('closest', x, y, halo, start)
2364 def find_enclosed(self, x1, y1, x2, y2):
2365 """Return all items in rectangle defined
2366 by X1,Y1,X2,Y2."""
2367 return self.find('enclosed', x1, y1, x2, y2)
2368 def find_overlapping(self, x1, y1, x2, y2):
2369 """Return all items which overlap the rectangle
2370 defined by X1,Y1,X2,Y2."""
2371 return self.find('overlapping', x1, y1, x2, y2)
2372 def find_withtag(self, tagOrId):
2373 """Return all items with TAGORID."""
2374 return self.find('withtag', tagOrId)
2375 def focus(self, *args):
2376 """Set focus to the first item specified in ARGS."""
2377 return self.tk.call((self._w, 'focus') + args)
2378 def gettags(self, *args):
2379 """Return tags associated with the first item specified in ARGS."""
2380 return self.tk.splitlist(
2381 self.tk.call((self._w, 'gettags') + args))
2382 def icursor(self, *args):
2383 """Set cursor at position POS in the item identified by TAGORID.
2384 In ARGS TAGORID must be first."""
2385 self.tk.call((self._w, 'icursor') + args)
2386 def index(self, *args):
2387 """Return position of cursor as integer in item specified in ARGS."""
2388 return getint(self.tk.call((self._w, 'index') + args))
2389 def insert(self, *args):
2390 """Insert TEXT in item TAGORID at position POS. ARGS must
2391 be TAGORID POS TEXT."""
2392 self.tk.call((self._w, 'insert') + args)
2393 def itemcget(self, tagOrId, option):
2394 """Return the resource value for an OPTION for item TAGORID."""
2395 return self.tk.call(
2396 (self._w, 'itemcget') + (tagOrId, '-'+option))
2397 def itemconfigure(self, tagOrId, cnf=None, **kw):
2398 """Configure resources of an item TAGORID.
2399
2400 The values for resources are specified as keyword
2401 arguments. To get an overview about
2402 the allowed keyword arguments call the method without arguments.
2403 """
2404 return self._configure(('itemconfigure', tagOrId), cnf, kw)
2405 itemconfig = itemconfigure
2406 # lower, tkraise/lift hide Misc.lower, Misc.tkraise/lift,
2407 # so the preferred name for them is tag_lower, tag_raise
2408 # (similar to tag_bind, and similar to the Text widget);
2409 # unfortunately can't delete the old ones yet (maybe in 1.6)
2410 def tag_lower(self, *args):
2411 """Lower an item TAGORID given in ARGS
2412 (optional below another item)."""
2413 self.tk.call((self._w, 'lower') + args)
2414 lower = tag_lower
2415 def move(self, *args):
2416 """Move an item TAGORID given in ARGS."""
2417 self.tk.call((self._w, 'move') + args)
2418 def postscript(self, cnf={}, **kw):
2419 """Print the contents of the canvas to a postscript
2420 file. Valid options: colormap, colormode, file, fontmap,
2421 height, pageanchor, pageheight, pagewidth, pagex, pagey,
2422 rotate, witdh, x, y."""
2423 return self.tk.call((self._w, 'postscript') +
2424 self._options(cnf, kw))
2425 def tag_raise(self, *args):
2426 """Raise an item TAGORID given in ARGS
2427 (optional above another item)."""
2428 self.tk.call((self._w, 'raise') + args)
2429 lift = tkraise = tag_raise
2430 def scale(self, *args):
2431 """Scale item TAGORID with XORIGIN, YORIGIN, XSCALE, YSCALE."""
2432 self.tk.call((self._w, 'scale') + args)
2433 def scan_mark(self, x, y):
2434 """Remember the current X, Y coordinates."""
2435 self.tk.call(self._w, 'scan', 'mark', x, y)
2436 def scan_dragto(self, x, y, gain=10):
2437 """Adjust the view of the canvas to GAIN times the
2438 difference between X and Y and the coordinates given in
2439 scan_mark."""
2440 self.tk.call(self._w, 'scan', 'dragto', x, y, gain)
2441 def select_adjust(self, tagOrId, index):
2442 """Adjust the end of the selection near the cursor of an item TAGORID to index."""
2443 self.tk.call(self._w, 'select', 'adjust', tagOrId, index)
2444 def select_clear(self):
2445 """Clear the selection if it is in this widget."""
2446 self.tk.call(self._w, 'select', 'clear')
2447 def select_from(self, tagOrId, index):
2448 """Set the fixed end of a selection in item TAGORID to INDEX."""
2449 self.tk.call(self._w, 'select', 'from', tagOrId, index)
2450 def select_item(self):
2451 """Return the item which has the selection."""
2452 return self.tk.call(self._w, 'select', 'item') or None
2453 def select_to(self, tagOrId, index):
2454 """Set the variable end of a selection in item TAGORID to INDEX."""
2455 self.tk.call(self._w, 'select', 'to', tagOrId, index)
2456 def type(self, tagOrId):
2457 """Return the type of the item TAGORID."""
2458 return self.tk.call(self._w, 'type', tagOrId) or None
Georg Brandl33cece02008-05-20 06:58:21 +00002459
2460class Checkbutton(Widget):
2461 """Checkbutton widget which is either in on- or off-state."""
2462 def __init__(self, master=None, cnf={}, **kw):
2463 """Construct a checkbutton widget with the parent MASTER.
2464
2465 Valid resource names: activebackground, activeforeground, anchor,
2466 background, bd, bg, bitmap, borderwidth, command, cursor,
2467 disabledforeground, fg, font, foreground, height,
2468 highlightbackground, highlightcolor, highlightthickness, image,
2469 indicatoron, justify, offvalue, onvalue, padx, pady, relief,
2470 selectcolor, selectimage, state, takefocus, text, textvariable,
2471 underline, variable, width, wraplength."""
2472 Widget.__init__(self, master, 'checkbutton', cnf, kw)
2473 def deselect(self):
2474 """Put the button in off-state."""
2475 self.tk.call(self._w, 'deselect')
2476 def flash(self):
2477 """Flash the button."""
2478 self.tk.call(self._w, 'flash')
2479 def invoke(self):
2480 """Toggle the button and invoke a command if given as resource."""
2481 return self.tk.call(self._w, 'invoke')
2482 def select(self):
2483 """Put the button in on-state."""
2484 self.tk.call(self._w, 'select')
2485 def toggle(self):
2486 """Toggle the button."""
2487 self.tk.call(self._w, 'toggle')
2488
Guilherme Poloe45f0172009-08-14 14:36:45 +00002489class Entry(Widget, XView):
Martin Panter53ae0ba2016-02-10 05:44:01 +00002490 """Entry widget which allows displaying simple text."""
Georg Brandl33cece02008-05-20 06:58:21 +00002491 def __init__(self, master=None, cnf={}, **kw):
2492 """Construct an entry widget with the parent MASTER.
2493
2494 Valid resource names: background, bd, bg, borderwidth, cursor,
2495 exportselection, fg, font, foreground, highlightbackground,
2496 highlightcolor, highlightthickness, insertbackground,
2497 insertborderwidth, insertofftime, insertontime, insertwidth,
2498 invalidcommand, invcmd, justify, relief, selectbackground,
2499 selectborderwidth, selectforeground, show, state, takefocus,
2500 textvariable, validate, validatecommand, vcmd, width,
2501 xscrollcommand."""
2502 Widget.__init__(self, master, 'entry', cnf, kw)
2503 def delete(self, first, last=None):
2504 """Delete text from FIRST to LAST (not included)."""
2505 self.tk.call(self._w, 'delete', first, last)
2506 def get(self):
2507 """Return the text."""
2508 return self.tk.call(self._w, 'get')
2509 def icursor(self, index):
2510 """Insert cursor at INDEX."""
2511 self.tk.call(self._w, 'icursor', index)
2512 def index(self, index):
2513 """Return position of cursor."""
2514 return getint(self.tk.call(
2515 self._w, 'index', index))
2516 def insert(self, index, string):
2517 """Insert STRING at INDEX."""
2518 self.tk.call(self._w, 'insert', index, string)
2519 def scan_mark(self, x):
2520 """Remember the current X, Y coordinates."""
2521 self.tk.call(self._w, 'scan', 'mark', x)
2522 def scan_dragto(self, x):
2523 """Adjust the view of the canvas to 10 times the
2524 difference between X and Y and the coordinates given in
2525 scan_mark."""
2526 self.tk.call(self._w, 'scan', 'dragto', x)
2527 def selection_adjust(self, index):
2528 """Adjust the end of the selection near the cursor to INDEX."""
2529 self.tk.call(self._w, 'selection', 'adjust', index)
2530 select_adjust = selection_adjust
2531 def selection_clear(self):
2532 """Clear the selection if it is in this widget."""
2533 self.tk.call(self._w, 'selection', 'clear')
2534 select_clear = selection_clear
2535 def selection_from(self, index):
2536 """Set the fixed end of a selection to INDEX."""
2537 self.tk.call(self._w, 'selection', 'from', index)
2538 select_from = selection_from
2539 def selection_present(self):
Guilherme Polo75e1f992009-08-14 14:43:43 +00002540 """Return True if there are characters selected in the entry, False
2541 otherwise."""
Georg Brandl33cece02008-05-20 06:58:21 +00002542 return self.tk.getboolean(
2543 self.tk.call(self._w, 'selection', 'present'))
2544 select_present = selection_present
2545 def selection_range(self, start, end):
2546 """Set the selection from START to END (not included)."""
2547 self.tk.call(self._w, 'selection', 'range', start, end)
2548 select_range = selection_range
2549 def selection_to(self, index):
2550 """Set the variable end of a selection to INDEX."""
2551 self.tk.call(self._w, 'selection', 'to', index)
2552 select_to = selection_to
Georg Brandl33cece02008-05-20 06:58:21 +00002553
2554class Frame(Widget):
2555 """Frame widget which may contain other widgets and can have a 3D border."""
2556 def __init__(self, master=None, cnf={}, **kw):
2557 """Construct a frame widget with the parent MASTER.
2558
2559 Valid resource names: background, bd, bg, borderwidth, class,
2560 colormap, container, cursor, height, highlightbackground,
2561 highlightcolor, highlightthickness, relief, takefocus, visual, width."""
2562 cnf = _cnfmerge((cnf, kw))
2563 extra = ()
Benjamin Peterson6e3dbbd2009-10-09 22:15:50 +00002564 if 'class_' in cnf:
Georg Brandl33cece02008-05-20 06:58:21 +00002565 extra = ('-class', cnf['class_'])
2566 del cnf['class_']
Benjamin Peterson6e3dbbd2009-10-09 22:15:50 +00002567 elif 'class' in cnf:
Georg Brandl33cece02008-05-20 06:58:21 +00002568 extra = ('-class', cnf['class'])
2569 del cnf['class']
2570 Widget.__init__(self, master, 'frame', cnf, {}, extra)
2571
2572class Label(Widget):
2573 """Label widget which can display text and bitmaps."""
2574 def __init__(self, master=None, cnf={}, **kw):
2575 """Construct a label widget with the parent MASTER.
2576
2577 STANDARD OPTIONS
2578
2579 activebackground, activeforeground, anchor,
2580 background, bitmap, borderwidth, cursor,
2581 disabledforeground, font, foreground,
2582 highlightbackground, highlightcolor,
2583 highlightthickness, image, justify,
2584 padx, pady, relief, takefocus, text,
2585 textvariable, underline, wraplength
2586
2587 WIDGET-SPECIFIC OPTIONS
2588
2589 height, state, width
2590
2591 """
2592 Widget.__init__(self, master, 'label', cnf, kw)
2593
Guilherme Poloe45f0172009-08-14 14:36:45 +00002594class Listbox(Widget, XView, YView):
Georg Brandl33cece02008-05-20 06:58:21 +00002595 """Listbox widget which can display a list of strings."""
2596 def __init__(self, master=None, cnf={}, **kw):
2597 """Construct a listbox widget with the parent MASTER.
2598
2599 Valid resource names: background, bd, bg, borderwidth, cursor,
2600 exportselection, fg, font, foreground, height, highlightbackground,
2601 highlightcolor, highlightthickness, relief, selectbackground,
2602 selectborderwidth, selectforeground, selectmode, setgrid, takefocus,
2603 width, xscrollcommand, yscrollcommand, listvariable."""
2604 Widget.__init__(self, master, 'listbox', cnf, kw)
2605 def activate(self, index):
2606 """Activate item identified by INDEX."""
2607 self.tk.call(self._w, 'activate', index)
Serhiy Storchakaf94686f2014-06-02 21:30:53 +03002608 def bbox(self, index):
Georg Brandl33cece02008-05-20 06:58:21 +00002609 """Return a tuple of X1,Y1,X2,Y2 coordinates for a rectangle
Serhiy Storchakaf94686f2014-06-02 21:30:53 +03002610 which encloses the item identified by the given index."""
2611 return self._getints(self.tk.call(self._w, 'bbox', index)) or None
Georg Brandl33cece02008-05-20 06:58:21 +00002612 def curselection(self):
Serhiy Storchakaf94686f2014-06-02 21:30:53 +03002613 """Return the indices of currently selected item."""
2614 return self._getints(self.tk.call(self._w, 'curselection')) or ()
Georg Brandl33cece02008-05-20 06:58:21 +00002615 def delete(self, first, last=None):
Serhiy Storchaka417367a2014-06-02 16:50:03 +03002616 """Delete items from FIRST to LAST (included)."""
Georg Brandl33cece02008-05-20 06:58:21 +00002617 self.tk.call(self._w, 'delete', first, last)
2618 def get(self, first, last=None):
Serhiy Storchaka417367a2014-06-02 16:50:03 +03002619 """Get list of items from FIRST to LAST (included)."""
Serhiy Storchakaf94686f2014-06-02 21:30:53 +03002620 if last is not None:
Georg Brandl33cece02008-05-20 06:58:21 +00002621 return self.tk.splitlist(self.tk.call(
2622 self._w, 'get', first, last))
2623 else:
2624 return self.tk.call(self._w, 'get', first)
2625 def index(self, index):
2626 """Return index of item identified with INDEX."""
2627 i = self.tk.call(self._w, 'index', index)
2628 if i == 'none': return None
2629 return getint(i)
2630 def insert(self, index, *elements):
2631 """Insert ELEMENTS at INDEX."""
2632 self.tk.call((self._w, 'insert', index) + elements)
2633 def nearest(self, y):
2634 """Get index of item which is nearest to y coordinate Y."""
2635 return getint(self.tk.call(
2636 self._w, 'nearest', y))
2637 def scan_mark(self, x, y):
2638 """Remember the current X, Y coordinates."""
2639 self.tk.call(self._w, 'scan', 'mark', x, y)
2640 def scan_dragto(self, x, y):
2641 """Adjust the view of the listbox to 10 times the
2642 difference between X and Y and the coordinates given in
2643 scan_mark."""
2644 self.tk.call(self._w, 'scan', 'dragto', x, y)
2645 def see(self, index):
2646 """Scroll such that INDEX is visible."""
2647 self.tk.call(self._w, 'see', index)
2648 def selection_anchor(self, index):
2649 """Set the fixed end oft the selection to INDEX."""
2650 self.tk.call(self._w, 'selection', 'anchor', index)
2651 select_anchor = selection_anchor
2652 def selection_clear(self, first, last=None):
Serhiy Storchaka417367a2014-06-02 16:50:03 +03002653 """Clear the selection from FIRST to LAST (included)."""
Georg Brandl33cece02008-05-20 06:58:21 +00002654 self.tk.call(self._w,
2655 'selection', 'clear', first, last)
2656 select_clear = selection_clear
2657 def selection_includes(self, index):
2658 """Return 1 if INDEX is part of the selection."""
2659 return self.tk.getboolean(self.tk.call(
2660 self._w, 'selection', 'includes', index))
2661 select_includes = selection_includes
2662 def selection_set(self, first, last=None):
Serhiy Storchaka417367a2014-06-02 16:50:03 +03002663 """Set the selection from FIRST to LAST (included) without
Georg Brandl33cece02008-05-20 06:58:21 +00002664 changing the currently selected elements."""
2665 self.tk.call(self._w, 'selection', 'set', first, last)
2666 select_set = selection_set
2667 def size(self):
2668 """Return the number of elements in the listbox."""
2669 return getint(self.tk.call(self._w, 'size'))
Georg Brandl33cece02008-05-20 06:58:21 +00002670 def itemcget(self, index, option):
2671 """Return the resource value for an ITEM and an OPTION."""
2672 return self.tk.call(
2673 (self._w, 'itemcget') + (index, '-'+option))
2674 def itemconfigure(self, index, cnf=None, **kw):
2675 """Configure resources of an ITEM.
2676
2677 The values for resources are specified as keyword arguments.
2678 To get an overview about the allowed keyword arguments
2679 call the method without arguments.
2680 Valid resource names: background, bg, foreground, fg,
2681 selectbackground, selectforeground."""
2682 return self._configure(('itemconfigure', index), cnf, kw)
2683 itemconfig = itemconfigure
2684
2685class Menu(Widget):
Martin Panter53ae0ba2016-02-10 05:44:01 +00002686 """Menu widget which allows displaying menu bars, pull-down menus and pop-up menus."""
Georg Brandl33cece02008-05-20 06:58:21 +00002687 def __init__(self, master=None, cnf={}, **kw):
2688 """Construct menu widget with the parent MASTER.
2689
2690 Valid resource names: activebackground, activeborderwidth,
2691 activeforeground, background, bd, bg, borderwidth, cursor,
2692 disabledforeground, fg, font, foreground, postcommand, relief,
2693 selectcolor, takefocus, tearoff, tearoffcommand, title, type."""
2694 Widget.__init__(self, master, 'menu', cnf, kw)
2695 def tk_bindForTraversal(self):
Serhiy Storchaka2ce9ddd2014-07-25 12:23:08 +03002696 # obsolete since Tk 4.0
2697 import warnings
2698 warnings.warn('tk_bindForTraversal() does nothing and '
2699 'will be removed in 3.6',
2700 DeprecationWarning, stacklevel=2)
Georg Brandl33cece02008-05-20 06:58:21 +00002701 def tk_mbPost(self):
2702 self.tk.call('tk_mbPost', self._w)
2703 def tk_mbUnpost(self):
2704 self.tk.call('tk_mbUnpost')
2705 def tk_traverseToMenu(self, char):
2706 self.tk.call('tk_traverseToMenu', self._w, char)
2707 def tk_traverseWithinMenu(self, char):
2708 self.tk.call('tk_traverseWithinMenu', self._w, char)
2709 def tk_getMenuButtons(self):
2710 return self.tk.call('tk_getMenuButtons', self._w)
2711 def tk_nextMenu(self, count):
2712 self.tk.call('tk_nextMenu', count)
2713 def tk_nextMenuEntry(self, count):
2714 self.tk.call('tk_nextMenuEntry', count)
2715 def tk_invokeMenu(self):
2716 self.tk.call('tk_invokeMenu', self._w)
2717 def tk_firstMenu(self):
2718 self.tk.call('tk_firstMenu', self._w)
2719 def tk_mbButtonDown(self):
2720 self.tk.call('tk_mbButtonDown', self._w)
2721 def tk_popup(self, x, y, entry=""):
2722 """Post the menu at position X,Y with entry ENTRY."""
2723 self.tk.call('tk_popup', self._w, x, y, entry)
2724 def activate(self, index):
2725 """Activate entry at INDEX."""
2726 self.tk.call(self._w, 'activate', index)
2727 def add(self, itemType, cnf={}, **kw):
2728 """Internal function."""
2729 self.tk.call((self._w, 'add', itemType) +
2730 self._options(cnf, kw))
2731 def add_cascade(self, cnf={}, **kw):
2732 """Add hierarchical menu item."""
2733 self.add('cascade', cnf or kw)
2734 def add_checkbutton(self, cnf={}, **kw):
2735 """Add checkbutton menu item."""
2736 self.add('checkbutton', cnf or kw)
2737 def add_command(self, cnf={}, **kw):
2738 """Add command menu item."""
2739 self.add('command', cnf or kw)
2740 def add_radiobutton(self, cnf={}, **kw):
2741 """Addd radio menu item."""
2742 self.add('radiobutton', cnf or kw)
2743 def add_separator(self, cnf={}, **kw):
2744 """Add separator."""
2745 self.add('separator', cnf or kw)
2746 def insert(self, index, itemType, cnf={}, **kw):
2747 """Internal function."""
2748 self.tk.call((self._w, 'insert', index, itemType) +
2749 self._options(cnf, kw))
2750 def insert_cascade(self, index, cnf={}, **kw):
2751 """Add hierarchical menu item at INDEX."""
2752 self.insert(index, 'cascade', cnf or kw)
2753 def insert_checkbutton(self, index, cnf={}, **kw):
2754 """Add checkbutton menu item at INDEX."""
2755 self.insert(index, 'checkbutton', cnf or kw)
2756 def insert_command(self, index, cnf={}, **kw):
2757 """Add command menu item at INDEX."""
2758 self.insert(index, 'command', cnf or kw)
2759 def insert_radiobutton(self, index, cnf={}, **kw):
2760 """Addd radio menu item at INDEX."""
2761 self.insert(index, 'radiobutton', cnf or kw)
2762 def insert_separator(self, index, cnf={}, **kw):
2763 """Add separator at INDEX."""
2764 self.insert(index, 'separator', cnf or kw)
2765 def delete(self, index1, index2=None):
Hirokazu Yamamotob9828f62008-11-03 18:03:06 +00002766 """Delete menu items between INDEX1 and INDEX2 (included)."""
Robert Schuppenies14646332008-08-10 11:01:53 +00002767 if index2 is None:
2768 index2 = index1
Hirokazu Yamamotob9828f62008-11-03 18:03:06 +00002769
2770 num_index1, num_index2 = self.index(index1), self.index(index2)
2771 if (num_index1 is None) or (num_index2 is None):
2772 num_index1, num_index2 = 0, -1
2773
2774 for i in range(num_index1, num_index2 + 1):
2775 if 'command' in self.entryconfig(i):
2776 c = str(self.entrycget(i, 'command'))
2777 if c:
2778 self.deletecommand(c)
Georg Brandl33cece02008-05-20 06:58:21 +00002779 self.tk.call(self._w, 'delete', index1, index2)
Georg Brandl33cece02008-05-20 06:58:21 +00002780 def entrycget(self, index, option):
Serhiy Storchaka9a118f12016-04-17 09:37:36 +03002781 """Return the resource value of a menu item for OPTION at INDEX."""
Georg Brandl33cece02008-05-20 06:58:21 +00002782 return self.tk.call(self._w, 'entrycget', index, '-' + option)
2783 def entryconfigure(self, index, cnf=None, **kw):
2784 """Configure a menu item at INDEX."""
2785 return self._configure(('entryconfigure', index), cnf, kw)
2786 entryconfig = entryconfigure
2787 def index(self, index):
2788 """Return the index of a menu item identified by INDEX."""
2789 i = self.tk.call(self._w, 'index', index)
2790 if i == 'none': return None
2791 return getint(i)
2792 def invoke(self, index):
2793 """Invoke a menu item identified by INDEX and execute
2794 the associated command."""
2795 return self.tk.call(self._w, 'invoke', index)
2796 def post(self, x, y):
2797 """Display a menu at position X,Y."""
2798 self.tk.call(self._w, 'post', x, y)
2799 def type(self, index):
2800 """Return the type of the menu item at INDEX."""
2801 return self.tk.call(self._w, 'type', index)
2802 def unpost(self):
2803 """Unmap a menu."""
2804 self.tk.call(self._w, 'unpost')
2805 def yposition(self, index):
2806 """Return the y-position of the topmost pixel of the menu item at INDEX."""
2807 return getint(self.tk.call(
2808 self._w, 'yposition', index))
2809
2810class Menubutton(Widget):
2811 """Menubutton widget, obsolete since Tk8.0."""
2812 def __init__(self, master=None, cnf={}, **kw):
2813 Widget.__init__(self, master, 'menubutton', cnf, kw)
2814
2815class Message(Widget):
2816 """Message widget to display multiline text. Obsolete since Label does it too."""
2817 def __init__(self, master=None, cnf={}, **kw):
2818 Widget.__init__(self, master, 'message', cnf, kw)
2819
2820class Radiobutton(Widget):
2821 """Radiobutton widget which shows only one of several buttons in on-state."""
2822 def __init__(self, master=None, cnf={}, **kw):
2823 """Construct a radiobutton widget with the parent MASTER.
2824
2825 Valid resource names: activebackground, activeforeground, anchor,
2826 background, bd, bg, bitmap, borderwidth, command, cursor,
2827 disabledforeground, fg, font, foreground, height,
2828 highlightbackground, highlightcolor, highlightthickness, image,
2829 indicatoron, justify, padx, pady, relief, selectcolor, selectimage,
2830 state, takefocus, text, textvariable, underline, value, variable,
2831 width, wraplength."""
2832 Widget.__init__(self, master, 'radiobutton', cnf, kw)
2833 def deselect(self):
2834 """Put the button in off-state."""
2835
2836 self.tk.call(self._w, 'deselect')
2837 def flash(self):
2838 """Flash the button."""
2839 self.tk.call(self._w, 'flash')
2840 def invoke(self):
2841 """Toggle the button and invoke a command if given as resource."""
2842 return self.tk.call(self._w, 'invoke')
2843 def select(self):
2844 """Put the button in on-state."""
2845 self.tk.call(self._w, 'select')
2846
2847class Scale(Widget):
2848 """Scale widget which can display a numerical scale."""
2849 def __init__(self, master=None, cnf={}, **kw):
2850 """Construct a scale widget with the parent MASTER.
2851
2852 Valid resource names: activebackground, background, bigincrement, bd,
2853 bg, borderwidth, command, cursor, digits, fg, font, foreground, from,
2854 highlightbackground, highlightcolor, highlightthickness, label,
2855 length, orient, relief, repeatdelay, repeatinterval, resolution,
2856 showvalue, sliderlength, sliderrelief, state, takefocus,
2857 tickinterval, to, troughcolor, variable, width."""
2858 Widget.__init__(self, master, 'scale', cnf, kw)
2859 def get(self):
2860 """Get the current value as integer or float."""
2861 value = self.tk.call(self._w, 'get')
2862 try:
2863 return getint(value)
2864 except ValueError:
2865 return getdouble(value)
2866 def set(self, value):
2867 """Set the value to VALUE."""
2868 self.tk.call(self._w, 'set', value)
2869 def coords(self, value=None):
2870 """Return a tuple (X,Y) of the point along the centerline of the
2871 trough that corresponds to VALUE or the current value if None is
2872 given."""
2873
2874 return self._getints(self.tk.call(self._w, 'coords', value))
2875 def identify(self, x, y):
2876 """Return where the point X,Y lies. Valid return values are "slider",
2877 "though1" and "though2"."""
2878 return self.tk.call(self._w, 'identify', x, y)
2879
2880class Scrollbar(Widget):
2881 """Scrollbar widget which displays a slider at a certain position."""
2882 def __init__(self, master=None, cnf={}, **kw):
2883 """Construct a scrollbar widget with the parent MASTER.
2884
2885 Valid resource names: activebackground, activerelief,
2886 background, bd, bg, borderwidth, command, cursor,
2887 elementborderwidth, highlightbackground,
2888 highlightcolor, highlightthickness, jump, orient,
2889 relief, repeatdelay, repeatinterval, takefocus,
2890 troughcolor, width."""
2891 Widget.__init__(self, master, 'scrollbar', cnf, kw)
2892 def activate(self, index):
2893 """Display the element at INDEX with activebackground and activerelief.
2894 INDEX can be "arrow1","slider" or "arrow2"."""
2895 self.tk.call(self._w, 'activate', index)
2896 def delta(self, deltax, deltay):
2897 """Return the fractional change of the scrollbar setting if it
2898 would be moved by DELTAX or DELTAY pixels."""
2899 return getdouble(
2900 self.tk.call(self._w, 'delta', deltax, deltay))
2901 def fraction(self, x, y):
2902 """Return the fractional value which corresponds to a slider
2903 position of X,Y."""
2904 return getdouble(self.tk.call(self._w, 'fraction', x, y))
2905 def identify(self, x, y):
2906 """Return the element under position X,Y as one of
2907 "arrow1","slider","arrow2" or ""."""
2908 return self.tk.call(self._w, 'identify', x, y)
2909 def get(self):
2910 """Return the current fractional values (upper and lower end)
2911 of the slider position."""
2912 return self._getdoubles(self.tk.call(self._w, 'get'))
2913 def set(self, *args):
2914 """Set the fractional values of the slider position (upper and
2915 lower ends as value between 0 and 1)."""
2916 self.tk.call((self._w, 'set') + args)
2917
2918
2919
Guilherme Poloe45f0172009-08-14 14:36:45 +00002920class Text(Widget, XView, YView):
Georg Brandl33cece02008-05-20 06:58:21 +00002921 """Text widget which can display text in various forms."""
2922 def __init__(self, master=None, cnf={}, **kw):
2923 """Construct a text widget with the parent MASTER.
2924
2925 STANDARD OPTIONS
2926
2927 background, borderwidth, cursor,
2928 exportselection, font, foreground,
2929 highlightbackground, highlightcolor,
2930 highlightthickness, insertbackground,
2931 insertborderwidth, insertofftime,
2932 insertontime, insertwidth, padx, pady,
2933 relief, selectbackground,
2934 selectborderwidth, selectforeground,
2935 setgrid, takefocus,
2936 xscrollcommand, yscrollcommand,
2937
2938 WIDGET-SPECIFIC OPTIONS
2939
2940 autoseparators, height, maxundo,
2941 spacing1, spacing2, spacing3,
2942 state, tabs, undo, width, wrap,
2943
2944 """
2945 Widget.__init__(self, master, 'text', cnf, kw)
2946 def bbox(self, *args):
2947 """Return a tuple of (x,y,width,height) which gives the bounding
2948 box of the visible part of the character at the index in ARGS."""
2949 return self._getints(
2950 self.tk.call((self._w, 'bbox') + args)) or None
2951 def tk_textSelectTo(self, index):
2952 self.tk.call('tk_textSelectTo', self._w, index)
2953 def tk_textBackspace(self):
2954 self.tk.call('tk_textBackspace', self._w)
2955 def tk_textIndexCloser(self, a, b, c):
2956 self.tk.call('tk_textIndexCloser', self._w, a, b, c)
2957 def tk_textResetAnchor(self, index):
2958 self.tk.call('tk_textResetAnchor', self._w, index)
2959 def compare(self, index1, op, index2):
2960 """Return whether between index INDEX1 and index INDEX2 the
2961 relation OP is satisfied. OP is one of <, <=, ==, >=, >, or !=."""
2962 return self.tk.getboolean(self.tk.call(
2963 self._w, 'compare', index1, op, index2))
2964 def debug(self, boolean=None):
2965 """Turn on the internal consistency checks of the B-Tree inside the text
2966 widget according to BOOLEAN."""
Serhiy Storchaka31b9c842013-11-03 14:28:29 +02002967 if boolean is None:
Serhiy Storchaka2bca9de2014-01-11 13:12:58 +02002968 return self.tk.getboolean(self.tk.call(self._w, 'debug'))
Serhiy Storchaka31b9c842013-11-03 14:28:29 +02002969 self.tk.call(self._w, 'debug', boolean)
Georg Brandl33cece02008-05-20 06:58:21 +00002970 def delete(self, index1, index2=None):
2971 """Delete the characters between INDEX1 and INDEX2 (not included)."""
2972 self.tk.call(self._w, 'delete', index1, index2)
2973 def dlineinfo(self, index):
2974 """Return tuple (x,y,width,height,baseline) giving the bounding box
2975 and baseline position of the visible part of the line containing
2976 the character at INDEX."""
2977 return self._getints(self.tk.call(self._w, 'dlineinfo', index))
2978 def dump(self, index1, index2=None, command=None, **kw):
2979 """Return the contents of the widget between index1 and index2.
2980
2981 The type of contents returned in filtered based on the keyword
2982 parameters; if 'all', 'image', 'mark', 'tag', 'text', or 'window' are
2983 given and true, then the corresponding items are returned. The result
2984 is a list of triples of the form (key, value, index). If none of the
2985 keywords are true then 'all' is used by default.
2986
2987 If the 'command' argument is given, it is called once for each element
2988 of the list of triples, with the values of each triple serving as the
2989 arguments to the function. In this case the list is not returned."""
2990 args = []
2991 func_name = None
2992 result = None
2993 if not command:
2994 # Never call the dump command without the -command flag, since the
2995 # output could involve Tcl quoting and would be a pain to parse
2996 # right. Instead just set the command to build a list of triples
2997 # as if we had done the parsing.
2998 result = []
2999 def append_triple(key, value, index, result=result):
3000 result.append((key, value, index))
3001 command = append_triple
3002 try:
3003 if not isinstance(command, str):
3004 func_name = command = self._register(command)
3005 args += ["-command", command]
3006 for key in kw:
3007 if kw[key]: args.append("-" + key)
3008 args.append(index1)
3009 if index2:
3010 args.append(index2)
3011 self.tk.call(self._w, "dump", *args)
3012 return result
3013 finally:
3014 if func_name:
3015 self.deletecommand(func_name)
3016
3017 ## new in tk8.4
3018 def edit(self, *args):
3019 """Internal method
3020
3021 This method controls the undo mechanism and
3022 the modified flag. The exact behavior of the
3023 command depends on the option argument that
3024 follows the edit argument. The following forms
3025 of the command are currently supported:
3026
3027 edit_modified, edit_redo, edit_reset, edit_separator
3028 and edit_undo
3029
3030 """
3031 return self.tk.call(self._w, 'edit', *args)
3032
3033 def edit_modified(self, arg=None):
3034 """Get or Set the modified flag
3035
3036 If arg is not specified, returns the modified
3037 flag of the widget. The insert, delete, edit undo and
3038 edit redo commands or the user can set or clear the
3039 modified flag. If boolean is specified, sets the
3040 modified flag of the widget to arg.
3041 """
3042 return self.edit("modified", arg)
3043
3044 def edit_redo(self):
3045 """Redo the last undone edit
3046
3047 When the undo option is true, reapplies the last
3048 undone edits provided no other edits were done since
3049 then. Generates an error when the redo stack is empty.
3050 Does nothing when the undo option is false.
3051 """
3052 return self.edit("redo")
3053
3054 def edit_reset(self):
3055 """Clears the undo and redo stacks
3056 """
3057 return self.edit("reset")
3058
3059 def edit_separator(self):
3060 """Inserts a separator (boundary) on the undo stack.
3061
3062 Does nothing when the undo option is false
3063 """
3064 return self.edit("separator")
3065
3066 def edit_undo(self):
3067 """Undoes the last edit action
3068
3069 If the undo option is true. An edit action is defined
3070 as all the insert and delete commands that are recorded
3071 on the undo stack in between two separators. Generates
3072 an error when the undo stack is empty. Does nothing
3073 when the undo option is false
3074 """
3075 return self.edit("undo")
3076
3077 def get(self, index1, index2=None):
3078 """Return the text from INDEX1 to INDEX2 (not included)."""
3079 return self.tk.call(self._w, 'get', index1, index2)
3080 # (Image commands are new in 8.0)
3081 def image_cget(self, index, option):
3082 """Return the value of OPTION of an embedded image at INDEX."""
3083 if option[:1] != "-":
3084 option = "-" + option
3085 if option[-1:] == "_":
3086 option = option[:-1]
3087 return self.tk.call(self._w, "image", "cget", index, option)
3088 def image_configure(self, index, cnf=None, **kw):
3089 """Configure an embedded image at INDEX."""
3090 return self._configure(('image', 'configure', index), cnf, kw)
3091 def image_create(self, index, cnf={}, **kw):
3092 """Create an embedded image at INDEX."""
3093 return self.tk.call(
3094 self._w, "image", "create", index,
3095 *self._options(cnf, kw))
3096 def image_names(self):
3097 """Return all names of embedded images in this widget."""
3098 return self.tk.call(self._w, "image", "names")
3099 def index(self, index):
3100 """Return the index in the form line.char for INDEX."""
3101 return str(self.tk.call(self._w, 'index', index))
3102 def insert(self, index, chars, *args):
3103 """Insert CHARS before the characters at INDEX. An additional
3104 tag can be given in ARGS. Additional CHARS and tags can follow in ARGS."""
3105 self.tk.call((self._w, 'insert', index, chars) + args)
3106 def mark_gravity(self, markName, direction=None):
3107 """Change the gravity of a mark MARKNAME to DIRECTION (LEFT or RIGHT).
3108 Return the current value if None is given for DIRECTION."""
3109 return self.tk.call(
3110 (self._w, 'mark', 'gravity', markName, direction))
3111 def mark_names(self):
3112 """Return all mark names."""
3113 return self.tk.splitlist(self.tk.call(
3114 self._w, 'mark', 'names'))
3115 def mark_set(self, markName, index):
3116 """Set mark MARKNAME before the character at INDEX."""
3117 self.tk.call(self._w, 'mark', 'set', markName, index)
3118 def mark_unset(self, *markNames):
3119 """Delete all marks in MARKNAMES."""
3120 self.tk.call((self._w, 'mark', 'unset') + markNames)
3121 def mark_next(self, index):
3122 """Return the name of the next mark after INDEX."""
3123 return self.tk.call(self._w, 'mark', 'next', index) or None
3124 def mark_previous(self, index):
3125 """Return the name of the previous mark before INDEX."""
3126 return self.tk.call(self._w, 'mark', 'previous', index) or None
3127 def scan_mark(self, x, y):
3128 """Remember the current X, Y coordinates."""
3129 self.tk.call(self._w, 'scan', 'mark', x, y)
3130 def scan_dragto(self, x, y):
3131 """Adjust the view of the text to 10 times the
3132 difference between X and Y and the coordinates given in
3133 scan_mark."""
3134 self.tk.call(self._w, 'scan', 'dragto', x, y)
3135 def search(self, pattern, index, stopindex=None,
3136 forwards=None, backwards=None, exact=None,
3137 regexp=None, nocase=None, count=None, elide=None):
3138 """Search PATTERN beginning from INDEX until STOPINDEX.
Guilherme Polod2ea0332009-02-09 16:41:09 +00003139 Return the index of the first character of a match or an
3140 empty string."""
Georg Brandl33cece02008-05-20 06:58:21 +00003141 args = [self._w, 'search']
3142 if forwards: args.append('-forwards')
3143 if backwards: args.append('-backwards')
3144 if exact: args.append('-exact')
3145 if regexp: args.append('-regexp')
3146 if nocase: args.append('-nocase')
3147 if elide: args.append('-elide')
3148 if count: args.append('-count'); args.append(count)
Guilherme Polod2ea0332009-02-09 16:41:09 +00003149 if pattern and pattern[0] == '-': args.append('--')
Georg Brandl33cece02008-05-20 06:58:21 +00003150 args.append(pattern)
3151 args.append(index)
3152 if stopindex: args.append(stopindex)
Guilherme Polo6d6c1fd2009-03-07 01:19:12 +00003153 return str(self.tk.call(tuple(args)))
Georg Brandl33cece02008-05-20 06:58:21 +00003154 def see(self, index):
3155 """Scroll such that the character at INDEX is visible."""
3156 self.tk.call(self._w, 'see', index)
3157 def tag_add(self, tagName, index1, *args):
3158 """Add tag TAGNAME to all characters between INDEX1 and index2 in ARGS.
3159 Additional pairs of indices may follow in ARGS."""
3160 self.tk.call(
3161 (self._w, 'tag', 'add', tagName, index1) + args)
3162 def tag_unbind(self, tagName, sequence, funcid=None):
3163 """Unbind for all characters with TAGNAME for event SEQUENCE the
3164 function identified with FUNCID."""
3165 self.tk.call(self._w, 'tag', 'bind', tagName, sequence, '')
3166 if funcid:
3167 self.deletecommand(funcid)
3168 def tag_bind(self, tagName, sequence, func, add=None):
3169 """Bind to all characters with TAGNAME at event SEQUENCE a call to function FUNC.
3170
3171 An additional boolean parameter ADD specifies whether FUNC will be
3172 called additionally to the other bound function or whether it will
3173 replace the previous function. See bind for the return value."""
3174 return self._bind((self._w, 'tag', 'bind', tagName),
3175 sequence, func, add)
3176 def tag_cget(self, tagName, option):
3177 """Return the value of OPTION for tag TAGNAME."""
3178 if option[:1] != '-':
3179 option = '-' + option
3180 if option[-1:] == '_':
3181 option = option[:-1]
3182 return self.tk.call(self._w, 'tag', 'cget', tagName, option)
3183 def tag_configure(self, tagName, cnf=None, **kw):
3184 """Configure a tag TAGNAME."""
3185 return self._configure(('tag', 'configure', tagName), cnf, kw)
3186 tag_config = tag_configure
3187 def tag_delete(self, *tagNames):
3188 """Delete all tags in TAGNAMES."""
3189 self.tk.call((self._w, 'tag', 'delete') + tagNames)
3190 def tag_lower(self, tagName, belowThis=None):
3191 """Change the priority of tag TAGNAME such that it is lower
3192 than the priority of BELOWTHIS."""
3193 self.tk.call(self._w, 'tag', 'lower', tagName, belowThis)
3194 def tag_names(self, index=None):
3195 """Return a list of all tag names."""
3196 return self.tk.splitlist(
3197 self.tk.call(self._w, 'tag', 'names', index))
3198 def tag_nextrange(self, tagName, index1, index2=None):
3199 """Return a list of start and end index for the first sequence of
3200 characters between INDEX1 and INDEX2 which all have tag TAGNAME.
3201 The text is searched forward from INDEX1."""
3202 return self.tk.splitlist(self.tk.call(
3203 self._w, 'tag', 'nextrange', tagName, index1, index2))
3204 def tag_prevrange(self, tagName, index1, index2=None):
3205 """Return a list of start and end index for the first sequence of
3206 characters between INDEX1 and INDEX2 which all have tag TAGNAME.
3207 The text is searched backwards from INDEX1."""
3208 return self.tk.splitlist(self.tk.call(
3209 self._w, 'tag', 'prevrange', tagName, index1, index2))
3210 def tag_raise(self, tagName, aboveThis=None):
3211 """Change the priority of tag TAGNAME such that it is higher
3212 than the priority of ABOVETHIS."""
3213 self.tk.call(
3214 self._w, 'tag', 'raise', tagName, aboveThis)
3215 def tag_ranges(self, tagName):
3216 """Return a list of ranges of text which have tag TAGNAME."""
3217 return self.tk.splitlist(self.tk.call(
3218 self._w, 'tag', 'ranges', tagName))
3219 def tag_remove(self, tagName, index1, index2=None):
3220 """Remove tag TAGNAME from all characters between INDEX1 and INDEX2."""
3221 self.tk.call(
3222 self._w, 'tag', 'remove', tagName, index1, index2)
3223 def window_cget(self, index, option):
3224 """Return the value of OPTION of an embedded window at INDEX."""
3225 if option[:1] != '-':
3226 option = '-' + option
3227 if option[-1:] == '_':
3228 option = option[:-1]
3229 return self.tk.call(self._w, 'window', 'cget', index, option)
3230 def window_configure(self, index, cnf=None, **kw):
3231 """Configure an embedded window at INDEX."""
3232 return self._configure(('window', 'configure', index), cnf, kw)
3233 window_config = window_configure
3234 def window_create(self, index, cnf={}, **kw):
3235 """Create a window at INDEX."""
3236 self.tk.call(
3237 (self._w, 'window', 'create', index)
3238 + self._options(cnf, kw))
3239 def window_names(self):
3240 """Return all names of embedded windows in this widget."""
3241 return self.tk.splitlist(
3242 self.tk.call(self._w, 'window', 'names'))
Georg Brandl33cece02008-05-20 06:58:21 +00003243 def yview_pickplace(self, *what):
3244 """Obsolete function, use see."""
3245 self.tk.call((self._w, 'yview', '-pickplace') + what)
3246
3247
3248class _setit:
3249 """Internal class. It wraps the command in the widget OptionMenu."""
3250 def __init__(self, var, value, callback=None):
3251 self.__value = value
3252 self.__var = var
3253 self.__callback = callback
3254 def __call__(self, *args):
3255 self.__var.set(self.__value)
3256 if self.__callback:
3257 self.__callback(self.__value, *args)
3258
3259class OptionMenu(Menubutton):
3260 """OptionMenu which allows the user to select a value from a menu."""
3261 def __init__(self, master, variable, value, *values, **kwargs):
3262 """Construct an optionmenu widget with the parent MASTER, with
3263 the resource textvariable set to VARIABLE, the initially selected
3264 value VALUE, the other menu values VALUES and an additional
3265 keyword argument command."""
3266 kw = {"borderwidth": 2, "textvariable": variable,
3267 "indicatoron": 1, "relief": RAISED, "anchor": "c",
3268 "highlightthickness": 2}
3269 Widget.__init__(self, master, "menubutton", kw)
3270 self.widgetName = 'tk_optionMenu'
3271 menu = self.__menu = Menu(self, name="menu", tearoff=0)
3272 self.menuname = menu._w
3273 # 'command' is the only supported keyword
3274 callback = kwargs.get('command')
Benjamin Peterson6e3dbbd2009-10-09 22:15:50 +00003275 if 'command' in kwargs:
Georg Brandl33cece02008-05-20 06:58:21 +00003276 del kwargs['command']
3277 if kwargs:
3278 raise TclError, 'unknown option -'+kwargs.keys()[0]
3279 menu.add_command(label=value,
3280 command=_setit(variable, value, callback))
3281 for v in values:
3282 menu.add_command(label=v,
3283 command=_setit(variable, v, callback))
3284 self["menu"] = menu
3285
3286 def __getitem__(self, name):
3287 if name == 'menu':
3288 return self.__menu
3289 return Widget.__getitem__(self, name)
3290
3291 def destroy(self):
3292 """Destroy this widget and the associated menu."""
3293 Menubutton.destroy(self)
3294 self.__menu = None
3295
3296class Image:
3297 """Base class for images."""
3298 _last_id = 0
3299 def __init__(self, imgtype, name=None, cnf={}, master=None, **kw):
3300 self.name = None
3301 if not master:
3302 master = _default_root
3303 if not master:
3304 raise RuntimeError, 'Too early to create image'
Serhiy Storchakad3ea0652014-08-24 09:07:09 +03003305 self.tk = getattr(master, 'tk', master)
Georg Brandl33cece02008-05-20 06:58:21 +00003306 if not name:
3307 Image._last_id += 1
3308 name = "pyimage%r" % (Image._last_id,) # tk itself would use image<x>
3309 # The following is needed for systems where id(x)
3310 # can return a negative number, such as Linux/m68k:
3311 if name[0] == '-': name = '_' + name[1:]
3312 if kw and cnf: cnf = _cnfmerge((cnf, kw))
3313 elif kw: cnf = kw
3314 options = ()
3315 for k, v in cnf.items():
Benjamin Petersonde055992009-10-09 22:05:45 +00003316 if hasattr(v, '__call__'):
Georg Brandl33cece02008-05-20 06:58:21 +00003317 v = self._register(v)
Serhiy Storchaka04fa7042014-07-31 07:48:14 +03003318 elif k in ('data', 'maskdata'):
3319 v = self.tk._createbytearray(v)
Georg Brandl33cece02008-05-20 06:58:21 +00003320 options = options + ('-'+k, v)
3321 self.tk.call(('image', 'create', imgtype, name,) + options)
3322 self.name = name
3323 def __str__(self): return self.name
3324 def __del__(self):
3325 if self.name:
3326 try:
3327 self.tk.call('image', 'delete', self.name)
3328 except TclError:
3329 # May happen if the root was destroyed
3330 pass
3331 def __setitem__(self, key, value):
3332 self.tk.call(self.name, 'configure', '-'+key, value)
3333 def __getitem__(self, key):
3334 return self.tk.call(self.name, 'configure', '-'+key)
3335 def configure(self, **kw):
3336 """Configure the image."""
3337 res = ()
3338 for k, v in _cnfmerge(kw).items():
3339 if v is not None:
3340 if k[-1] == '_': k = k[:-1]
Benjamin Petersonde055992009-10-09 22:05:45 +00003341 if hasattr(v, '__call__'):
Georg Brandl33cece02008-05-20 06:58:21 +00003342 v = self._register(v)
Serhiy Storchaka04fa7042014-07-31 07:48:14 +03003343 elif k in ('data', 'maskdata'):
3344 v = self.tk._createbytearray(v)
Georg Brandl33cece02008-05-20 06:58:21 +00003345 res = res + ('-'+k, v)
3346 self.tk.call((self.name, 'config') + res)
3347 config = configure
3348 def height(self):
3349 """Return the height of the image."""
3350 return getint(
3351 self.tk.call('image', 'height', self.name))
3352 def type(self):
3353 """Return the type of the imgage, e.g. "photo" or "bitmap"."""
3354 return self.tk.call('image', 'type', self.name)
3355 def width(self):
3356 """Return the width of the image."""
3357 return getint(
3358 self.tk.call('image', 'width', self.name))
3359
3360class PhotoImage(Image):
3361 """Widget which can display colored images in GIF, PPM/PGM format."""
3362 def __init__(self, name=None, cnf={}, master=None, **kw):
3363 """Create an image with NAME.
3364
3365 Valid resource names: data, format, file, gamma, height, palette,
3366 width."""
3367 Image.__init__(self, 'photo', name, cnf, master, **kw)
3368 def blank(self):
3369 """Display a transparent image."""
3370 self.tk.call(self.name, 'blank')
3371 def cget(self, option):
3372 """Return the value of OPTION."""
3373 return self.tk.call(self.name, 'cget', '-' + option)
3374 # XXX config
3375 def __getitem__(self, key):
3376 return self.tk.call(self.name, 'cget', '-' + key)
3377 # XXX copy -from, -to, ...?
3378 def copy(self):
3379 """Return a new PhotoImage with the same image as this widget."""
Serhiy Storchakad3ea0652014-08-24 09:07:09 +03003380 destImage = PhotoImage(master=self.tk)
Georg Brandl33cece02008-05-20 06:58:21 +00003381 self.tk.call(destImage, 'copy', self.name)
3382 return destImage
Terry Jan Reedyca761002016-03-11 15:30:27 -05003383 def zoom(self, x, y=''):
Georg Brandl33cece02008-05-20 06:58:21 +00003384 """Return a new PhotoImage with the same image as this widget
Terry Jan Reedyca761002016-03-11 15:30:27 -05003385 but zoom it with a factor of x in the X direction and y in the Y
3386 direction. If y is not given, the default value is the same as x.
3387 """
Serhiy Storchakad3ea0652014-08-24 09:07:09 +03003388 destImage = PhotoImage(master=self.tk)
Georg Brandl33cece02008-05-20 06:58:21 +00003389 if y=='': y=x
3390 self.tk.call(destImage, 'copy', self.name, '-zoom',x,y)
3391 return destImage
Terry Jan Reedyca761002016-03-11 15:30:27 -05003392 def subsample(self, x, y=''):
Georg Brandl33cece02008-05-20 06:58:21 +00003393 """Return a new PhotoImage based on the same image as this widget
Terry Jan Reedyca761002016-03-11 15:30:27 -05003394 but use only every Xth or Yth pixel. If y is not given, the
3395 default value is the same as x.
3396 """
Serhiy Storchakad3ea0652014-08-24 09:07:09 +03003397 destImage = PhotoImage(master=self.tk)
Georg Brandl33cece02008-05-20 06:58:21 +00003398 if y=='': y=x
3399 self.tk.call(destImage, 'copy', self.name, '-subsample',x,y)
3400 return destImage
3401 def get(self, x, y):
3402 """Return the color (red, green, blue) of the pixel at X,Y."""
3403 return self.tk.call(self.name, 'get', x, y)
3404 def put(self, data, to=None):
Mark Dickinson3e4caeb2009-02-21 20:27:01 +00003405 """Put row formatted colors to image starting from
Georg Brandl33cece02008-05-20 06:58:21 +00003406 position TO, e.g. image.put("{red green} {blue yellow}", to=(4,6))"""
3407 args = (self.name, 'put', data)
3408 if to:
3409 if to[0] == '-to':
3410 to = to[1:]
3411 args = args + ('-to',) + tuple(to)
3412 self.tk.call(args)
3413 # XXX read
3414 def write(self, filename, format=None, from_coords=None):
3415 """Write image to file FILENAME in FORMAT starting from
3416 position FROM_COORDS."""
3417 args = (self.name, 'write', filename)
3418 if format:
3419 args = args + ('-format', format)
3420 if from_coords:
3421 args = args + ('-from',) + tuple(from_coords)
3422 self.tk.call(args)
3423
3424class BitmapImage(Image):
3425 """Widget which can display a bitmap."""
3426 def __init__(self, name=None, cnf={}, master=None, **kw):
3427 """Create a bitmap with NAME.
3428
3429 Valid resource names: background, data, file, foreground, maskdata, maskfile."""
3430 Image.__init__(self, 'bitmap', name, cnf, master, **kw)
3431
Serhiy Storchaka9be238d2014-01-07 19:32:58 +02003432def image_names():
3433 return _default_root.tk.splitlist(_default_root.tk.call('image', 'names'))
3434
3435def image_types():
3436 return _default_root.tk.splitlist(_default_root.tk.call('image', 'types'))
Georg Brandl33cece02008-05-20 06:58:21 +00003437
3438
Guilherme Poloe45f0172009-08-14 14:36:45 +00003439class Spinbox(Widget, XView):
Georg Brandl33cece02008-05-20 06:58:21 +00003440 """spinbox widget."""
3441 def __init__(self, master=None, cnf={}, **kw):
3442 """Construct a spinbox widget with the parent MASTER.
3443
3444 STANDARD OPTIONS
3445
3446 activebackground, background, borderwidth,
3447 cursor, exportselection, font, foreground,
3448 highlightbackground, highlightcolor,
3449 highlightthickness, insertbackground,
3450 insertborderwidth, insertofftime,
3451 insertontime, insertwidth, justify, relief,
3452 repeatdelay, repeatinterval,
3453 selectbackground, selectborderwidth
3454 selectforeground, takefocus, textvariable
3455 xscrollcommand.
3456
3457 WIDGET-SPECIFIC OPTIONS
3458
3459 buttonbackground, buttoncursor,
3460 buttondownrelief, buttonuprelief,
3461 command, disabledbackground,
3462 disabledforeground, format, from,
3463 invalidcommand, increment,
3464 readonlybackground, state, to,
3465 validate, validatecommand values,
3466 width, wrap,
3467 """
3468 Widget.__init__(self, master, 'spinbox', cnf, kw)
3469
3470 def bbox(self, index):
3471 """Return a tuple of X1,Y1,X2,Y2 coordinates for a
3472 rectangle which encloses the character given by index.
3473
3474 The first two elements of the list give the x and y
3475 coordinates of the upper-left corner of the screen
3476 area covered by the character (in pixels relative
3477 to the widget) and the last two elements give the
3478 width and height of the character, in pixels. The
3479 bounding box may refer to a region outside the
3480 visible area of the window.
3481 """
Serhiy Storchaka8630f162013-11-03 14:13:08 +02003482 return self._getints(self.tk.call(self._w, 'bbox', index)) or None
Georg Brandl33cece02008-05-20 06:58:21 +00003483
3484 def delete(self, first, last=None):
3485 """Delete one or more elements of the spinbox.
3486
3487 First is the index of the first character to delete,
3488 and last is the index of the character just after
3489 the last one to delete. If last isn't specified it
3490 defaults to first+1, i.e. a single character is
3491 deleted. This command returns an empty string.
3492 """
3493 return self.tk.call(self._w, 'delete', first, last)
3494
3495 def get(self):
3496 """Returns the spinbox's string"""
3497 return self.tk.call(self._w, 'get')
3498
3499 def icursor(self, index):
3500 """Alter the position of the insertion cursor.
3501
3502 The insertion cursor will be displayed just before
3503 the character given by index. Returns an empty string
3504 """
3505 return self.tk.call(self._w, 'icursor', index)
3506
3507 def identify(self, x, y):
3508 """Returns the name of the widget at position x, y
3509
3510 Return value is one of: none, buttondown, buttonup, entry
3511 """
3512 return self.tk.call(self._w, 'identify', x, y)
3513
3514 def index(self, index):
3515 """Returns the numerical index corresponding to index
3516 """
3517 return self.tk.call(self._w, 'index', index)
3518
3519 def insert(self, index, s):
3520 """Insert string s at index
3521
3522 Returns an empty string.
3523 """
3524 return self.tk.call(self._w, 'insert', index, s)
3525
3526 def invoke(self, element):
3527 """Causes the specified element to be invoked
3528
3529 The element could be buttondown or buttonup
3530 triggering the action associated with it.
3531 """
3532 return self.tk.call(self._w, 'invoke', element)
3533
3534 def scan(self, *args):
3535 """Internal function."""
3536 return self._getints(
3537 self.tk.call((self._w, 'scan') + args)) or ()
3538
3539 def scan_mark(self, x):
3540 """Records x and the current view in the spinbox window;
3541
3542 used in conjunction with later scan dragto commands.
3543 Typically this command is associated with a mouse button
3544 press in the widget. It returns an empty string.
3545 """
3546 return self.scan("mark", x)
3547
3548 def scan_dragto(self, x):
3549 """Compute the difference between the given x argument
3550 and the x argument to the last scan mark command
3551
3552 It then adjusts the view left or right by 10 times the
3553 difference in x-coordinates. This command is typically
3554 associated with mouse motion events in the widget, to
3555 produce the effect of dragging the spinbox at high speed
3556 through the window. The return value is an empty string.
3557 """
3558 return self.scan("dragto", x)
3559
3560 def selection(self, *args):
3561 """Internal function."""
3562 return self._getints(
3563 self.tk.call((self._w, 'selection') + args)) or ()
3564
3565 def selection_adjust(self, index):
3566 """Locate the end of the selection nearest to the character
3567 given by index,
3568
3569 Then adjust that end of the selection to be at index
3570 (i.e including but not going beyond index). The other
3571 end of the selection is made the anchor point for future
3572 select to commands. If the selection isn't currently in
3573 the spinbox, then a new selection is created to include
3574 the characters between index and the most recent selection
3575 anchor point, inclusive. Returns an empty string.
3576 """
3577 return self.selection("adjust", index)
3578
3579 def selection_clear(self):
3580 """Clear the selection
3581
3582 If the selection isn't in this widget then the
3583 command has no effect. Returns an empty string.
3584 """
3585 return self.selection("clear")
3586
3587 def selection_element(self, element=None):
3588 """Sets or gets the currently selected element.
3589
3590 If a spinbutton element is specified, it will be
3591 displayed depressed
3592 """
3593 return self.selection("element", element)
3594
3595###########################################################################
3596
3597class LabelFrame(Widget):
3598 """labelframe widget."""
3599 def __init__(self, master=None, cnf={}, **kw):
3600 """Construct a labelframe widget with the parent MASTER.
3601
3602 STANDARD OPTIONS
3603
3604 borderwidth, cursor, font, foreground,
3605 highlightbackground, highlightcolor,
3606 highlightthickness, padx, pady, relief,
3607 takefocus, text
3608
3609 WIDGET-SPECIFIC OPTIONS
3610
3611 background, class, colormap, container,
3612 height, labelanchor, labelwidget,
3613 visual, width
3614 """
3615 Widget.__init__(self, master, 'labelframe', cnf, kw)
3616
3617########################################################################
3618
3619class PanedWindow(Widget):
3620 """panedwindow widget."""
3621 def __init__(self, master=None, cnf={}, **kw):
3622 """Construct a panedwindow widget with the parent MASTER.
3623
3624 STANDARD OPTIONS
3625
3626 background, borderwidth, cursor, height,
3627 orient, relief, width
3628
3629 WIDGET-SPECIFIC OPTIONS
3630
3631 handlepad, handlesize, opaqueresize,
3632 sashcursor, sashpad, sashrelief,
3633 sashwidth, showhandle,
3634 """
3635 Widget.__init__(self, master, 'panedwindow', cnf, kw)
3636
3637 def add(self, child, **kw):
3638 """Add a child widget to the panedwindow in a new pane.
3639
3640 The child argument is the name of the child widget
3641 followed by pairs of arguments that specify how to
Guilherme Polo1c6787f2009-05-31 21:31:21 +00003642 manage the windows. The possible options and values
3643 are the ones accepted by the paneconfigure method.
Georg Brandl33cece02008-05-20 06:58:21 +00003644 """
3645 self.tk.call((self._w, 'add', child) + self._options(kw))
3646
3647 def remove(self, child):
3648 """Remove the pane containing child from the panedwindow
3649
3650 All geometry management options for child will be forgotten.
3651 """
3652 self.tk.call(self._w, 'forget', child)
3653 forget=remove
3654
3655 def identify(self, x, y):
3656 """Identify the panedwindow component at point x, y
3657
3658 If the point is over a sash or a sash handle, the result
3659 is a two element list containing the index of the sash or
3660 handle, and a word indicating whether it is over a sash
3661 or a handle, such as {0 sash} or {2 handle}. If the point
3662 is over any other part of the panedwindow, the result is
3663 an empty list.
3664 """
3665 return self.tk.call(self._w, 'identify', x, y)
3666
3667 def proxy(self, *args):
3668 """Internal function."""
3669 return self._getints(
3670 self.tk.call((self._w, 'proxy') + args)) or ()
3671
3672 def proxy_coord(self):
3673 """Return the x and y pair of the most recent proxy location
3674 """
3675 return self.proxy("coord")
3676
3677 def proxy_forget(self):
3678 """Remove the proxy from the display.
3679 """
3680 return self.proxy("forget")
3681
3682 def proxy_place(self, x, y):
3683 """Place the proxy at the given x and y coordinates.
3684 """
3685 return self.proxy("place", x, y)
3686
3687 def sash(self, *args):
3688 """Internal function."""
3689 return self._getints(
3690 self.tk.call((self._w, 'sash') + args)) or ()
3691
3692 def sash_coord(self, index):
3693 """Return the current x and y pair for the sash given by index.
3694
3695 Index must be an integer between 0 and 1 less than the
3696 number of panes in the panedwindow. The coordinates given are
3697 those of the top left corner of the region containing the sash.
3698 pathName sash dragto index x y This command computes the
3699 difference between the given coordinates and the coordinates
3700 given to the last sash coord command for the given sash. It then
3701 moves that sash the computed difference. The return value is the
3702 empty string.
3703 """
3704 return self.sash("coord", index)
3705
3706 def sash_mark(self, index):
3707 """Records x and y for the sash given by index;
3708
3709 Used in conjunction with later dragto commands to move the sash.
3710 """
3711 return self.sash("mark", index)
3712
3713 def sash_place(self, index, x, y):
3714 """Place the sash given by index at the given coordinates
3715 """
3716 return self.sash("place", index, x, y)
3717
3718 def panecget(self, child, option):
3719 """Query a management option for window.
3720
3721 Option may be any value allowed by the paneconfigure subcommand
3722 """
3723 return self.tk.call(
3724 (self._w, 'panecget') + (child, '-'+option))
3725
3726 def paneconfigure(self, tagOrId, cnf=None, **kw):
3727 """Query or modify the management options for window.
3728
3729 If no option is specified, returns a list describing all
3730 of the available options for pathName. If option is
3731 specified with no value, then the command returns a list
3732 describing the one named option (this list will be identical
3733 to the corresponding sublist of the value returned if no
3734 option is specified). If one or more option-value pairs are
3735 specified, then the command modifies the given widget
3736 option(s) to have the given value(s); in this case the
3737 command returns an empty string. The following options
3738 are supported:
3739
3740 after window
3741 Insert the window after the window specified. window
3742 should be the name of a window already managed by pathName.
3743 before window
3744 Insert the window before the window specified. window
3745 should be the name of a window already managed by pathName.
3746 height size
3747 Specify a height for the window. The height will be the
3748 outer dimension of the window including its border, if
3749 any. If size is an empty string, or if -height is not
3750 specified, then the height requested internally by the
3751 window will be used initially; the height may later be
3752 adjusted by the movement of sashes in the panedwindow.
3753 Size may be any value accepted by Tk_GetPixels.
3754 minsize n
3755 Specifies that the size of the window cannot be made
3756 less than n. This constraint only affects the size of
3757 the widget in the paned dimension -- the x dimension
3758 for horizontal panedwindows, the y dimension for
3759 vertical panedwindows. May be any value accepted by
3760 Tk_GetPixels.
3761 padx n
3762 Specifies a non-negative value indicating how much
3763 extra space to leave on each side of the window in
3764 the X-direction. The value may have any of the forms
3765 accepted by Tk_GetPixels.
3766 pady n
3767 Specifies a non-negative value indicating how much
3768 extra space to leave on each side of the window in
3769 the Y-direction. The value may have any of the forms
3770 accepted by Tk_GetPixels.
3771 sticky style
3772 If a window's pane is larger than the requested
3773 dimensions of the window, this option may be used
3774 to position (or stretch) the window within its pane.
3775 Style is a string that contains zero or more of the
3776 characters n, s, e or w. The string can optionally
3777 contains spaces or commas, but they are ignored. Each
3778 letter refers to a side (north, south, east, or west)
3779 that the window will "stick" to. If both n and s
3780 (or e and w) are specified, the window will be
3781 stretched to fill the entire height (or width) of
3782 its cavity.
3783 width size
3784 Specify a width for the window. The width will be
3785 the outer dimension of the window including its
3786 border, if any. If size is an empty string, or
3787 if -width is not specified, then the width requested
3788 internally by the window will be used initially; the
3789 width may later be adjusted by the movement of sashes
3790 in the panedwindow. Size may be any value accepted by
3791 Tk_GetPixels.
3792
3793 """
3794 if cnf is None and not kw:
Serhiy Storchakaec773cc2013-12-25 16:35:20 +02003795 return self._getconfigure(self._w, 'paneconfigure', tagOrId)
Georg Brandl33cece02008-05-20 06:58:21 +00003796 if type(cnf) == StringType and not kw:
Serhiy Storchakaec773cc2013-12-25 16:35:20 +02003797 return self._getconfigure1(
3798 self._w, 'paneconfigure', tagOrId, '-'+cnf)
Georg Brandl33cece02008-05-20 06:58:21 +00003799 self.tk.call((self._w, 'paneconfigure', tagOrId) +
3800 self._options(cnf, kw))
3801 paneconfig = paneconfigure
3802
3803 def panes(self):
3804 """Returns an ordered list of the child panes."""
Serhiy Storchaka9be238d2014-01-07 19:32:58 +02003805 return self.tk.splitlist(self.tk.call(self._w, 'panes'))
Georg Brandl33cece02008-05-20 06:58:21 +00003806
3807######################################################################
3808# Extensions:
3809
3810class Studbutton(Button):
3811 def __init__(self, master=None, cnf={}, **kw):
3812 Widget.__init__(self, master, 'studbutton', cnf, kw)
3813 self.bind('<Any-Enter>', self.tkButtonEnter)
3814 self.bind('<Any-Leave>', self.tkButtonLeave)
3815 self.bind('<1>', self.tkButtonDown)
3816 self.bind('<ButtonRelease-1>', self.tkButtonUp)
3817
3818class Tributton(Button):
3819 def __init__(self, master=None, cnf={}, **kw):
3820 Widget.__init__(self, master, 'tributton', cnf, kw)
3821 self.bind('<Any-Enter>', self.tkButtonEnter)
3822 self.bind('<Any-Leave>', self.tkButtonLeave)
3823 self.bind('<1>', self.tkButtonDown)
3824 self.bind('<ButtonRelease-1>', self.tkButtonUp)
3825 self['fg'] = self['bg']
3826 self['activebackground'] = self['bg']
3827
3828######################################################################
3829# Test:
3830
3831def _test():
3832 root = Tk()
3833 text = "This is Tcl/Tk version %s" % TclVersion
3834 if TclVersion >= 8.1:
3835 try:
3836 text = text + unicode("\nThis should be a cedilla: \347",
3837 "iso-8859-1")
3838 except NameError:
3839 pass # no unicode support
3840 label = Label(root, text=text)
3841 label.pack()
3842 test = Button(root, text="Click me!",
3843 command=lambda root=root: root.test.configure(
3844 text="[%s]" % root.test['text']))
3845 test.pack()
3846 root.test = test
3847 quit = Button(root, text="QUIT", command=root.destroy)
3848 quit.pack()
3849 # The following three commands are needed so the window pops
3850 # up on top on Windows...
3851 root.iconify()
3852 root.update()
3853 root.deiconify()
3854 root.mainloop()
3855
3856if __name__ == '__main__':
3857 _test()