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