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