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