blob: c5bf136f80b7c0504bccf524697b33992ca078da [file] [log] [blame]
Guido van Rossum5917ecb2000-06-29 16:30:50 +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,
Guido van Rossuma0adb922001-09-01 18:29:55 +00006Checkbutton, Scale, Listbox, Scrollbar, OptionMenu. Properties of the
7widgets are specified with keyword arguments. Keyword arguments have
8the same name as the corresponding resource under Tk.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00009
10Widgets are positioned with one of the geometry managers Place, Pack
11or Grid. These managers can be called with methods place, pack, grid
12available in every Widget.
13
Guido van Rossuma0adb922001-09-01 18:29:55 +000014Actions are bound to events by resources (e.g. keyword argument
15command) or with the method bind.
Guido van Rossum5917ecb2000-06-29 16:30:50 +000016
17Example (Hello, World):
18import Tkinter
19from Tkconstants import *
20tk = Tkinter.Tk()
21frame = Tkinter.Frame(tk, relief=RIDGE, borderwidth=2)
22frame.pack(fill=BOTH,expand=1)
23label = Tkinter.Label(frame, text="Hello, World")
24label.pack(fill=X, expand=1)
25button = Tkinter.Button(frame,text="Exit",command=tk.destroy)
26button.pack(side=BOTTOM)
27tk.mainloop()
28"""
Guido van Rossum2dcf5291994-07-06 09:23:20 +000029
Guido van Rossum37dcab11996-05-16 16:00:19 +000030__version__ = "$Revision$"
31
Guido van Rossumf8d579c1999-01-04 18:06:45 +000032import sys
33if sys.platform == "win32":
Fredrik Lundh06d28152000-08-09 18:03:12 +000034 import FixTk # Attempt to configure Tcl/Tk without requiring PATH
Guido van Rossumf8d579c1999-01-04 18:06:45 +000035import _tkinter # If this fails your Python may not be configured for Tk
Guido van Rossum95806091997-02-15 18:33:24 +000036tkinter = _tkinter # b/w compat for export
37TclError = _tkinter.TclError
Guido van Rossum7e9394a1995-03-17 16:21:33 +000038from types import *
Guido van Rossuma5773dd1995-09-07 19:22:00 +000039from Tkconstants import *
Guido van Rossumf0c891a1998-04-29 21:43:36 +000040try:
Fredrik Lundh06d28152000-08-09 18:03:12 +000041 import MacOS; _MacOS = MacOS; del MacOS
Guido van Rossumf0c891a1998-04-29 21:43:36 +000042except ImportError:
Fredrik Lundh06d28152000-08-09 18:03:12 +000043 _MacOS = None
Guido van Rossum18468821994-06-20 07:49:28 +000044
Eric S. Raymondfc170b12001-02-09 11:51:27 +000045TkVersion = float(_tkinter.TK_VERSION)
46TclVersion = float(_tkinter.TCL_VERSION)
Guido van Rossum18468821994-06-20 07:49:28 +000047
Guido van Rossumd6615ab1997-08-05 02:35:01 +000048READABLE = _tkinter.READABLE
49WRITABLE = _tkinter.WRITABLE
50EXCEPTION = _tkinter.EXCEPTION
Guido van Rossumf53c86c1997-08-14 14:15:54 +000051
52# These are not always defined, e.g. not on Win32 with Tk 8.0 :-(
53try: _tkinter.createfilehandler
54except AttributeError: _tkinter.createfilehandler = None
55try: _tkinter.deletefilehandler
56except AttributeError: _tkinter.deletefilehandler = None
Fredrik Lundh06d28152000-08-09 18:03:12 +000057
58
Guido van Rossum2dcf5291994-07-06 09:23:20 +000059def _flatten(tuple):
Fredrik Lundh06d28152000-08-09 18:03:12 +000060 """Internal function."""
61 res = ()
62 for item in tuple:
63 if type(item) in (TupleType, ListType):
64 res = res + _flatten(item)
65 elif item is not None:
66 res = res + (item,)
67 return res
Guido van Rossum2dcf5291994-07-06 09:23:20 +000068
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +000069try: _flatten = _tkinter._flatten
70except AttributeError: pass
71
Guido van Rossum2dcf5291994-07-06 09:23:20 +000072def _cnfmerge(cnfs):
Fredrik Lundh06d28152000-08-09 18:03:12 +000073 """Internal function."""
74 if type(cnfs) is DictionaryType:
75 return cnfs
76 elif type(cnfs) in (NoneType, StringType):
77 return cnfs
78 else:
79 cnf = {}
80 for c in _flatten(cnfs):
81 try:
82 cnf.update(c)
83 except (AttributeError, TypeError), msg:
84 print "_cnfmerge: fallback due to:", msg
85 for k, v in c.items():
86 cnf[k] = v
87 return cnf
Guido van Rossum2dcf5291994-07-06 09:23:20 +000088
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +000089try: _cnfmerge = _tkinter._cnfmerge
90except AttributeError: pass
91
Guido van Rossum2dcf5291994-07-06 09:23:20 +000092class Event:
Fredrik Lundh06d28152000-08-09 18:03:12 +000093 """Container for the properties of an event.
Guido van Rossum5917ecb2000-06-29 16:30:50 +000094
Fredrik Lundh06d28152000-08-09 18:03:12 +000095 Instances of this type are generated if one of the following events occurs:
Guido van Rossum5917ecb2000-06-29 16:30:50 +000096
Fredrik Lundh06d28152000-08-09 18:03:12 +000097 KeyPress, KeyRelease - for keyboard events
98 ButtonPress, ButtonRelease, Motion, Enter, Leave, MouseWheel - for mouse events
99 Visibility, Unmap, Map, Expose, FocusIn, FocusOut, Circulate,
100 Colormap, Gravity, Reparent, Property, Destroy, Activate,
101 Deactivate - for window events.
102
103 If a callback function for one of these events is registered
104 using bind, bind_all, bind_class, or tag_bind, the callback is
105 called with an Event as first argument. It will have the
106 following attributes (in braces are the event types for which
107 the attribute is valid):
108
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000109 serial - serial number of event
Fredrik Lundh06d28152000-08-09 18:03:12 +0000110 num - mouse button pressed (ButtonPress, ButtonRelease)
111 focus - whether the window has the focus (Enter, Leave)
112 height - height of the exposed window (Configure, Expose)
113 width - width of the exposed window (Configure, Expose)
114 keycode - keycode of the pressed key (KeyPress, KeyRelease)
115 state - state of the event as a number (ButtonPress, ButtonRelease,
116 Enter, KeyPress, KeyRelease,
117 Leave, Motion)
118 state - state as a string (Visibility)
119 time - when the event occurred
120 x - x-position of the mouse
121 y - y-position of the mouse
122 x_root - x-position of the mouse on the screen
123 (ButtonPress, ButtonRelease, KeyPress, KeyRelease, Motion)
124 y_root - y-position of the mouse on the screen
125 (ButtonPress, ButtonRelease, KeyPress, KeyRelease, Motion)
126 char - pressed character (KeyPress, KeyRelease)
127 send_event - see X/Windows documentation
128 keysym - keysym of the the event as a string (KeyPress, KeyRelease)
129 keysym_num - keysym of the event as a number (KeyPress, KeyRelease)
130 type - type of the event as a number
131 widget - widget in which the event occurred
132 delta - delta of wheel movement (MouseWheel)
133 """
134 pass
Guido van Rossum2dcf5291994-07-06 09:23:20 +0000135
Guido van Rossumc4570481998-03-20 20:45:49 +0000136_support_default_root = 1
Guido van Rossumaec5dc91994-06-27 07:55:12 +0000137_default_root = None
138
Guido van Rossumc4570481998-03-20 20:45:49 +0000139def NoDefaultRoot():
Fredrik Lundh06d28152000-08-09 18:03:12 +0000140 """Inhibit setting of default root window.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000141
Fredrik Lundh06d28152000-08-09 18:03:12 +0000142 Call this function to inhibit that the first instance of
143 Tk is used for windows without an explicit parent window.
144 """
145 global _support_default_root
146 _support_default_root = 0
147 global _default_root
148 _default_root = None
149 del _default_root
Guido van Rossumc4570481998-03-20 20:45:49 +0000150
Guido van Rossum45853db1994-06-20 12:19:19 +0000151def _tkerror(err):
Fredrik Lundh06d28152000-08-09 18:03:12 +0000152 """Internal function."""
153 pass
Guido van Rossum18468821994-06-20 07:49:28 +0000154
Guido van Rossum97aeca11994-07-07 13:12:12 +0000155def _exit(code='0'):
Fredrik Lundh06d28152000-08-09 18:03:12 +0000156 """Internal function. Calling it will throw the exception SystemExit."""
157 raise SystemExit, code
Guido van Rossum97aeca11994-07-07 13:12:12 +0000158
Guido van Rossumaec5dc91994-06-27 07:55:12 +0000159_varnum = 0
160class Variable:
Fredrik Lundh06d28152000-08-09 18:03:12 +0000161 """Internal class. Base class to define value holders for e.g. buttons."""
162 _default = ""
163 def __init__(self, master=None):
164 """Construct a variable with an optional MASTER as master widget.
165 The variable is named PY_VAR_number in Tcl.
166 """
167 global _varnum
168 if not master:
169 master = _default_root
170 self._master = master
171 self._tk = master.tk
172 self._name = 'PY_VAR' + `_varnum`
173 _varnum = _varnum + 1
174 self.set(self._default)
175 def __del__(self):
176 """Unset the variable in Tcl."""
177 self._tk.globalunsetvar(self._name)
178 def __str__(self):
179 """Return the name of the variable in Tcl."""
180 return self._name
181 def set(self, value):
182 """Set the variable to VALUE."""
183 return self._tk.globalsetvar(self._name, value)
184 def trace_variable(self, mode, callback):
185 """Define a trace callback for the variable.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000186
Fredrik Lundh06d28152000-08-09 18:03:12 +0000187 MODE is one of "r", "w", "u" for read, write, undefine.
188 CALLBACK must be a function which is called when
189 the variable is read, written or undefined.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000190
Fredrik Lundh06d28152000-08-09 18:03:12 +0000191 Return the name of the callback.
192 """
193 cbname = self._master._register(callback)
194 self._tk.call("trace", "variable", self._name, mode, cbname)
195 return cbname
196 trace = trace_variable
197 def trace_vdelete(self, mode, cbname):
198 """Delete the trace callback for a variable.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000199
Fredrik Lundh06d28152000-08-09 18:03:12 +0000200 MODE is one of "r", "w", "u" for read, write, undefine.
201 CBNAME is the name of the callback returned from trace_variable or trace.
202 """
203 self._tk.call("trace", "vdelete", self._name, mode, cbname)
204 self._master.deletecommand(cbname)
205 def trace_vinfo(self):
206 """Return all trace callback information."""
207 return map(self._tk.split, self._tk.splitlist(
208 self._tk.call("trace", "vinfo", self._name)))
Guido van Rossumaec5dc91994-06-27 07:55:12 +0000209
210class StringVar(Variable):
Fredrik Lundh06d28152000-08-09 18:03:12 +0000211 """Value holder for strings variables."""
212 _default = ""
213 def __init__(self, master=None):
214 """Construct a string variable.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000215
Fredrik Lundh06d28152000-08-09 18:03:12 +0000216 MASTER can be given as master widget."""
217 Variable.__init__(self, master)
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000218
Fredrik Lundh06d28152000-08-09 18:03:12 +0000219 def get(self):
220 """Return value of variable as string."""
221 return self._tk.globalgetvar(self._name)
Guido van Rossumaec5dc91994-06-27 07:55:12 +0000222
223class IntVar(Variable):
Fredrik Lundh06d28152000-08-09 18:03:12 +0000224 """Value holder for integer variables."""
225 _default = 0
226 def __init__(self, master=None):
227 """Construct an integer variable.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000228
Fredrik Lundh06d28152000-08-09 18:03:12 +0000229 MASTER can be given as master widget."""
230 Variable.__init__(self, master)
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000231
Fredrik Lundh06d28152000-08-09 18:03:12 +0000232 def get(self):
233 """Return the value of the variable as an integer."""
234 return getint(self._tk.globalgetvar(self._name))
Guido van Rossumaec5dc91994-06-27 07:55:12 +0000235
236class DoubleVar(Variable):
Fredrik Lundh06d28152000-08-09 18:03:12 +0000237 """Value holder for float variables."""
238 _default = 0.0
239 def __init__(self, master=None):
240 """Construct a float variable.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000241
Fredrik Lundh06d28152000-08-09 18:03:12 +0000242 MASTER can be given as a master widget."""
243 Variable.__init__(self, master)
244
245 def get(self):
246 """Return the value of the variable as a float."""
247 return getdouble(self._tk.globalgetvar(self._name))
Guido van Rossumaec5dc91994-06-27 07:55:12 +0000248
249class BooleanVar(Variable):
Fredrik Lundh06d28152000-08-09 18:03:12 +0000250 """Value holder for boolean variables."""
251 _default = "false"
252 def __init__(self, master=None):
253 """Construct a boolean variable.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000254
Fredrik Lundh06d28152000-08-09 18:03:12 +0000255 MASTER can be given as a master widget."""
256 Variable.__init__(self, master)
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000257
Fredrik Lundh06d28152000-08-09 18:03:12 +0000258 def get(self):
259 """Return the value of the variable as 0 or 1."""
260 return self._tk.getboolean(self._tk.globalgetvar(self._name))
Guido van Rossumaec5dc91994-06-27 07:55:12 +0000261
Guido van Rossum35f67fb1995-08-04 03:50:29 +0000262def mainloop(n=0):
Fredrik Lundh06d28152000-08-09 18:03:12 +0000263 """Run the main loop of Tcl."""
264 _default_root.tk.mainloop(n)
Guido van Rossum2dcf5291994-07-06 09:23:20 +0000265
Guido van Rossum0132f691998-04-30 17:50:36 +0000266getint = int
Guido van Rossum2dcf5291994-07-06 09:23:20 +0000267
Guido van Rossum0132f691998-04-30 17:50:36 +0000268getdouble = float
Guido van Rossum2dcf5291994-07-06 09:23:20 +0000269
270def getboolean(s):
Fredrik Lundh06d28152000-08-09 18:03:12 +0000271 """Convert true and false to integer values 1 and 0."""
272 return _default_root.tk.getboolean(s)
Guido van Rossum2dcf5291994-07-06 09:23:20 +0000273
Guido van Rossum368e06b1997-11-07 20:38:49 +0000274# Methods defined on both toplevel and interior widgets
Guido van Rossum18468821994-06-20 07:49:28 +0000275class Misc:
Fredrik Lundh06d28152000-08-09 18:03:12 +0000276 """Internal class.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000277
Fredrik Lundh06d28152000-08-09 18:03:12 +0000278 Base class which defines methods common for interior widgets."""
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000279
Fredrik Lundh06d28152000-08-09 18:03:12 +0000280 # XXX font command?
281 _tclCommands = None
282 def destroy(self):
283 """Internal function.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000284
Fredrik Lundh06d28152000-08-09 18:03:12 +0000285 Delete all Tcl commands created for
286 this widget in the Tcl interpreter."""
287 if self._tclCommands is not None:
288 for name in self._tclCommands:
289 #print '- Tkinter: deleted command', name
290 self.tk.deletecommand(name)
291 self._tclCommands = None
292 def deletecommand(self, name):
293 """Internal function.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000294
Fredrik Lundh06d28152000-08-09 18:03:12 +0000295 Delete the Tcl command provided in NAME."""
296 #print '- Tkinter: deleted command', name
297 self.tk.deletecommand(name)
298 try:
299 self._tclCommands.remove(name)
300 except ValueError:
301 pass
302 def tk_strictMotif(self, boolean=None):
303 """Set Tcl internal variable, whether the look and feel
304 should adhere to Motif.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000305
Fredrik Lundh06d28152000-08-09 18:03:12 +0000306 A parameter of 1 means adhere to Motif (e.g. no color
307 change if mouse passes over slider).
308 Returns the set value."""
309 return self.tk.getboolean(self.tk.call(
310 'set', 'tk_strictMotif', boolean))
311 def tk_bisque(self):
312 """Change the color scheme to light brown as used in Tk 3.6 and before."""
313 self.tk.call('tk_bisque')
314 def tk_setPalette(self, *args, **kw):
315 """Set a new color scheme for all widget elements.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000316
Fredrik Lundh06d28152000-08-09 18:03:12 +0000317 A single color as argument will cause that all colors of Tk
318 widget elements are derived from this.
319 Alternatively several keyword parameters and its associated
320 colors can be given. The following keywords are valid:
321 activeBackground, foreground, selectColor,
322 activeForeground, highlightBackground, selectBackground,
323 background, highlightColor, selectForeground,
324 disabledForeground, insertBackground, troughColor."""
325 self.tk.call(('tk_setPalette',)
326 + _flatten(args) + _flatten(kw.items()))
327 def tk_menuBar(self, *args):
328 """Do not use. Needed in Tk 3.6 and earlier."""
329 pass # obsolete since Tk 4.0
330 def wait_variable(self, name='PY_VAR'):
331 """Wait until the variable is modified.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000332
Fredrik Lundh06d28152000-08-09 18:03:12 +0000333 A parameter of type IntVar, StringVar, DoubleVar or
334 BooleanVar must be given."""
335 self.tk.call('tkwait', 'variable', name)
336 waitvar = wait_variable # XXX b/w compat
337 def wait_window(self, window=None):
338 """Wait until a WIDGET is destroyed.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000339
Fredrik Lundh06d28152000-08-09 18:03:12 +0000340 If no parameter is given self is used."""
Fred Drake132dce22000-12-12 23:11:42 +0000341 if window is None:
Fredrik Lundh06d28152000-08-09 18:03:12 +0000342 window = self
343 self.tk.call('tkwait', 'window', window._w)
344 def wait_visibility(self, window=None):
345 """Wait until the visibility of a WIDGET changes
346 (e.g. it appears).
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000347
Fredrik Lundh06d28152000-08-09 18:03:12 +0000348 If no parameter is given self is used."""
Fred Drake132dce22000-12-12 23:11:42 +0000349 if window is None:
Fredrik Lundh06d28152000-08-09 18:03:12 +0000350 window = self
351 self.tk.call('tkwait', 'visibility', window._w)
352 def setvar(self, name='PY_VAR', value='1'):
353 """Set Tcl variable NAME to VALUE."""
354 self.tk.setvar(name, value)
355 def getvar(self, name='PY_VAR'):
356 """Return value of Tcl variable NAME."""
357 return self.tk.getvar(name)
358 getint = int
359 getdouble = float
360 def getboolean(self, s):
361 """Return 0 or 1 for Tcl boolean values true and false given as parameter."""
362 return self.tk.getboolean(s)
363 def focus_set(self):
364 """Direct input focus to this widget.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000365
Fredrik Lundh06d28152000-08-09 18:03:12 +0000366 If the application currently does not have the focus
367 this widget will get the focus if the application gets
368 the focus through the window manager."""
369 self.tk.call('focus', self._w)
370 focus = focus_set # XXX b/w compat?
371 def focus_force(self):
372 """Direct input focus to this widget even if the
373 application does not have the focus. Use with
374 caution!"""
375 self.tk.call('focus', '-force', self._w)
376 def focus_get(self):
377 """Return the widget which has currently the focus in the
378 application.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000379
Fredrik Lundh06d28152000-08-09 18:03:12 +0000380 Use focus_displayof to allow working with several
381 displays. Return None if application does not have
382 the focus."""
383 name = self.tk.call('focus')
384 if name == 'none' or not name: return None
385 return self._nametowidget(name)
386 def focus_displayof(self):
387 """Return the widget which has currently the focus on the
388 display where this widget is located.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000389
Fredrik Lundh06d28152000-08-09 18:03:12 +0000390 Return None if the application does not have the focus."""
391 name = self.tk.call('focus', '-displayof', self._w)
392 if name == 'none' or not name: return None
393 return self._nametowidget(name)
394 def focus_lastfor(self):
395 """Return the widget which would have the focus if top level
396 for this widget gets the focus from the window manager."""
397 name = self.tk.call('focus', '-lastfor', self._w)
398 if name == 'none' or not name: return None
399 return self._nametowidget(name)
400 def tk_focusFollowsMouse(self):
401 """The widget under mouse will get automatically focus. Can not
402 be disabled easily."""
403 self.tk.call('tk_focusFollowsMouse')
404 def tk_focusNext(self):
405 """Return the next widget in the focus order which follows
406 widget which has currently the focus.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000407
Fredrik Lundh06d28152000-08-09 18:03:12 +0000408 The focus order first goes to the next child, then to
409 the children of the child recursively and then to the
410 next sibling which is higher in the stacking order. A
411 widget is omitted if it has the takefocus resource set
412 to 0."""
413 name = self.tk.call('tk_focusNext', self._w)
414 if not name: return None
415 return self._nametowidget(name)
416 def tk_focusPrev(self):
417 """Return previous widget in the focus order. See tk_focusNext for details."""
418 name = self.tk.call('tk_focusPrev', self._w)
419 if not name: return None
420 return self._nametowidget(name)
421 def after(self, ms, func=None, *args):
422 """Call function once after given time.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000423
Fredrik Lundh06d28152000-08-09 18:03:12 +0000424 MS specifies the time in milliseconds. FUNC gives the
425 function which shall be called. Additional parameters
426 are given as parameters to the function call. Return
427 identifier to cancel scheduling with after_cancel."""
428 if not func:
429 # I'd rather use time.sleep(ms*0.001)
430 self.tk.call('after', ms)
431 else:
432 # XXX Disgusting hack to clean up after calling func
433 tmp = []
434 def callit(func=func, args=args, self=self, tmp=tmp):
435 try:
436 apply(func, args)
437 finally:
438 try:
439 self.deletecommand(tmp[0])
440 except TclError:
441 pass
442 name = self._register(callit)
443 tmp.append(name)
444 return self.tk.call('after', ms, name)
445 def after_idle(self, func, *args):
446 """Call FUNC once if the Tcl main loop has no event to
447 process.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000448
Fredrik Lundh06d28152000-08-09 18:03:12 +0000449 Return an identifier to cancel the scheduling with
450 after_cancel."""
451 return apply(self.after, ('idle', func) + args)
452 def after_cancel(self, id):
453 """Cancel scheduling of function identified with ID.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000454
Fredrik Lundh06d28152000-08-09 18:03:12 +0000455 Identifier returned by after or after_idle must be
456 given as first parameter."""
457 self.tk.call('after', 'cancel', id)
458 def bell(self, displayof=0):
459 """Ring a display's bell."""
460 self.tk.call(('bell',) + self._displayof(displayof))
461 # Clipboard handling:
462 def clipboard_clear(self, **kw):
463 """Clear the data in the Tk clipboard.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000464
Fredrik Lundh06d28152000-08-09 18:03:12 +0000465 A widget specified for the optional displayof keyword
466 argument specifies the target display."""
467 if not kw.has_key('displayof'): kw['displayof'] = self._w
468 self.tk.call(('clipboard', 'clear') + self._options(kw))
469 def clipboard_append(self, string, **kw):
470 """Append STRING to the Tk clipboard.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000471
Fredrik Lundh06d28152000-08-09 18:03:12 +0000472 A widget specified at the optional displayof keyword
473 argument specifies the target display. The clipboard
474 can be retrieved with selection_get."""
475 if not kw.has_key('displayof'): kw['displayof'] = self._w
476 self.tk.call(('clipboard', 'append') + self._options(kw)
477 + ('--', string))
478 # XXX grab current w/o window argument
479 def grab_current(self):
480 """Return widget which has currently the grab in this application
481 or None."""
482 name = self.tk.call('grab', 'current', self._w)
483 if not name: return None
484 return self._nametowidget(name)
485 def grab_release(self):
486 """Release grab for this widget if currently set."""
487 self.tk.call('grab', 'release', self._w)
488 def grab_set(self):
489 """Set grab for this widget.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000490
Fredrik Lundh06d28152000-08-09 18:03:12 +0000491 A grab directs all events to this and descendant
492 widgets in the application."""
493 self.tk.call('grab', 'set', self._w)
494 def grab_set_global(self):
495 """Set global grab for this widget.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000496
Fredrik Lundh06d28152000-08-09 18:03:12 +0000497 A global grab directs all events to this and
498 descendant widgets on the display. Use with caution -
499 other applications do not get events anymore."""
500 self.tk.call('grab', 'set', '-global', self._w)
501 def grab_status(self):
502 """Return None, "local" or "global" if this widget has
503 no, a local or a global grab."""
504 status = self.tk.call('grab', 'status', self._w)
505 if status == 'none': status = None
506 return status
507 def lower(self, belowThis=None):
508 """Lower this widget in the stacking order."""
509 self.tk.call('lower', self._w, belowThis)
510 def option_add(self, pattern, value, priority = None):
511 """Set a VALUE (second parameter) for an option
512 PATTERN (first parameter).
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000513
Fredrik Lundh06d28152000-08-09 18:03:12 +0000514 An optional third parameter gives the numeric priority
515 (defaults to 80)."""
516 self.tk.call('option', 'add', pattern, value, priority)
517 def option_clear(self):
518 """Clear the option database.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000519
Fredrik Lundh06d28152000-08-09 18:03:12 +0000520 It will be reloaded if option_add is called."""
521 self.tk.call('option', 'clear')
522 def option_get(self, name, className):
523 """Return the value for an option NAME for this widget
524 with CLASSNAME.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000525
Fredrik Lundh06d28152000-08-09 18:03:12 +0000526 Values with higher priority override lower values."""
527 return self.tk.call('option', 'get', self._w, name, className)
528 def option_readfile(self, fileName, priority = None):
529 """Read file FILENAME into the option database.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000530
Fredrik Lundh06d28152000-08-09 18:03:12 +0000531 An optional second parameter gives the numeric
532 priority."""
533 self.tk.call('option', 'readfile', fileName, priority)
534 def selection_clear(self, **kw):
535 """Clear the current X selection."""
536 if not kw.has_key('displayof'): kw['displayof'] = self._w
537 self.tk.call(('selection', 'clear') + self._options(kw))
538 def selection_get(self, **kw):
539 """Return the contents of the current X selection.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000540
Fredrik Lundh06d28152000-08-09 18:03:12 +0000541 A keyword parameter selection specifies the name of
542 the selection and defaults to PRIMARY. A keyword
543 parameter displayof specifies a widget on the display
544 to use."""
545 if not kw.has_key('displayof'): kw['displayof'] = self._w
546 return self.tk.call(('selection', 'get') + self._options(kw))
547 def selection_handle(self, command, **kw):
548 """Specify a function COMMAND to call if the X
549 selection owned by this widget is queried by another
550 application.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000551
Fredrik Lundh06d28152000-08-09 18:03:12 +0000552 This function must return the contents of the
553 selection. The function will be called with the
554 arguments OFFSET and LENGTH which allows the chunking
555 of very long selections. The following keyword
556 parameters can be provided:
557 selection - name of the selection (default PRIMARY),
558 type - type of the selection (e.g. STRING, FILE_NAME)."""
559 name = self._register(command)
560 self.tk.call(('selection', 'handle') + self._options(kw)
561 + (self._w, name))
562 def selection_own(self, **kw):
563 """Become owner of X selection.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000564
Fredrik Lundh06d28152000-08-09 18:03:12 +0000565 A keyword parameter selection specifies the name of
566 the selection (default PRIMARY)."""
567 self.tk.call(('selection', 'own') +
568 self._options(kw) + (self._w,))
569 def selection_own_get(self, **kw):
570 """Return owner of X selection.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000571
Fredrik Lundh06d28152000-08-09 18:03:12 +0000572 The following keyword parameter can
573 be provided:
574 selection - name of the selection (default PRIMARY),
575 type - type of the selection (e.g. STRING, FILE_NAME)."""
576 if not kw.has_key('displayof'): kw['displayof'] = self._w
577 name = self.tk.call(('selection', 'own') + self._options(kw))
578 if not name: return None
579 return self._nametowidget(name)
580 def send(self, interp, cmd, *args):
581 """Send Tcl command CMD to different interpreter INTERP to be executed."""
582 return self.tk.call(('send', interp, cmd) + args)
583 def lower(self, belowThis=None):
584 """Lower this widget in the stacking order."""
585 self.tk.call('lower', self._w, belowThis)
586 def tkraise(self, aboveThis=None):
587 """Raise this widget in the stacking order."""
588 self.tk.call('raise', self._w, aboveThis)
589 lift = tkraise
590 def colormodel(self, value=None):
591 """Useless. Not implemented in Tk."""
592 return self.tk.call('tk', 'colormodel', self._w, value)
593 def winfo_atom(self, name, displayof=0):
594 """Return integer which represents atom NAME."""
595 args = ('winfo', 'atom') + self._displayof(displayof) + (name,)
596 return getint(self.tk.call(args))
597 def winfo_atomname(self, id, displayof=0):
598 """Return name of atom with identifier ID."""
599 args = ('winfo', 'atomname') \
600 + self._displayof(displayof) + (id,)
601 return self.tk.call(args)
602 def winfo_cells(self):
603 """Return number of cells in the colormap for this widget."""
604 return getint(
605 self.tk.call('winfo', 'cells', self._w))
606 def winfo_children(self):
607 """Return a list of all widgets which are children of this widget."""
Martin v. Löwisf2041b82002-03-27 17:15:57 +0000608 result = []
609 for child in self.tk.splitlist(
610 self.tk.call('winfo', 'children', self._w)):
611 try:
612 # Tcl sometimes returns extra windows, e.g. for
613 # menus; those need to be skipped
614 result.append(self._nametowidget(child))
615 except KeyError:
616 pass
617 return result
618
Fredrik Lundh06d28152000-08-09 18:03:12 +0000619 def winfo_class(self):
620 """Return window class name of this widget."""
621 return self.tk.call('winfo', 'class', self._w)
622 def winfo_colormapfull(self):
623 """Return true if at the last color request the colormap was full."""
624 return self.tk.getboolean(
625 self.tk.call('winfo', 'colormapfull', self._w))
626 def winfo_containing(self, rootX, rootY, displayof=0):
627 """Return the widget which is at the root coordinates ROOTX, ROOTY."""
628 args = ('winfo', 'containing') \
629 + self._displayof(displayof) + (rootX, rootY)
630 name = self.tk.call(args)
631 if not name: return None
632 return self._nametowidget(name)
633 def winfo_depth(self):
634 """Return the number of bits per pixel."""
635 return getint(self.tk.call('winfo', 'depth', self._w))
636 def winfo_exists(self):
637 """Return true if this widget exists."""
638 return getint(
639 self.tk.call('winfo', 'exists', self._w))
640 def winfo_fpixels(self, number):
641 """Return the number of pixels for the given distance NUMBER
642 (e.g. "3c") as float."""
643 return getdouble(self.tk.call(
644 'winfo', 'fpixels', self._w, number))
645 def winfo_geometry(self):
646 """Return geometry string for this widget in the form "widthxheight+X+Y"."""
647 return self.tk.call('winfo', 'geometry', self._w)
648 def winfo_height(self):
649 """Return height of this widget."""
650 return getint(
651 self.tk.call('winfo', 'height', self._w))
652 def winfo_id(self):
653 """Return identifier ID for this widget."""
654 return self.tk.getint(
655 self.tk.call('winfo', 'id', self._w))
656 def winfo_interps(self, displayof=0):
657 """Return the name of all Tcl interpreters for this display."""
658 args = ('winfo', 'interps') + self._displayof(displayof)
659 return self.tk.splitlist(self.tk.call(args))
660 def winfo_ismapped(self):
661 """Return true if this widget is mapped."""
662 return getint(
663 self.tk.call('winfo', 'ismapped', self._w))
664 def winfo_manager(self):
665 """Return the window mananger name for this widget."""
666 return self.tk.call('winfo', 'manager', self._w)
667 def winfo_name(self):
668 """Return the name of this widget."""
669 return self.tk.call('winfo', 'name', self._w)
670 def winfo_parent(self):
671 """Return the name of the parent of this widget."""
672 return self.tk.call('winfo', 'parent', self._w)
673 def winfo_pathname(self, id, displayof=0):
674 """Return the pathname of the widget given by ID."""
675 args = ('winfo', 'pathname') \
676 + self._displayof(displayof) + (id,)
677 return self.tk.call(args)
678 def winfo_pixels(self, number):
679 """Rounded integer value of winfo_fpixels."""
680 return getint(
681 self.tk.call('winfo', 'pixels', self._w, number))
682 def winfo_pointerx(self):
683 """Return the x coordinate of the pointer on the root window."""
684 return getint(
685 self.tk.call('winfo', 'pointerx', self._w))
686 def winfo_pointerxy(self):
687 """Return a tuple of x and y coordinates of the pointer on the root window."""
688 return self._getints(
689 self.tk.call('winfo', 'pointerxy', self._w))
690 def winfo_pointery(self):
691 """Return the y coordinate of the pointer on the root window."""
692 return getint(
693 self.tk.call('winfo', 'pointery', self._w))
694 def winfo_reqheight(self):
695 """Return requested height of this widget."""
696 return getint(
697 self.tk.call('winfo', 'reqheight', self._w))
698 def winfo_reqwidth(self):
699 """Return requested width of this widget."""
700 return getint(
701 self.tk.call('winfo', 'reqwidth', self._w))
702 def winfo_rgb(self, color):
703 """Return tuple of decimal values for red, green, blue for
704 COLOR in this widget."""
705 return self._getints(
706 self.tk.call('winfo', 'rgb', self._w, color))
707 def winfo_rootx(self):
708 """Return x coordinate of upper left corner of this widget on the
709 root window."""
710 return getint(
711 self.tk.call('winfo', 'rootx', self._w))
712 def winfo_rooty(self):
713 """Return y coordinate of upper left corner of this widget on the
714 root window."""
715 return getint(
716 self.tk.call('winfo', 'rooty', self._w))
717 def winfo_screen(self):
718 """Return the screen name of this widget."""
719 return self.tk.call('winfo', 'screen', self._w)
720 def winfo_screencells(self):
721 """Return the number of the cells in the colormap of the screen
722 of this widget."""
723 return getint(
724 self.tk.call('winfo', 'screencells', self._w))
725 def winfo_screendepth(self):
726 """Return the number of bits per pixel of the root window of the
727 screen of this widget."""
728 return getint(
729 self.tk.call('winfo', 'screendepth', self._w))
730 def winfo_screenheight(self):
731 """Return the number of pixels of the height of the screen of this widget
732 in pixel."""
733 return getint(
734 self.tk.call('winfo', 'screenheight', self._w))
735 def winfo_screenmmheight(self):
736 """Return the number of pixels of the height of the screen of
737 this widget in mm."""
738 return getint(
739 self.tk.call('winfo', 'screenmmheight', self._w))
740 def winfo_screenmmwidth(self):
741 """Return the number of pixels of the width of the screen of
742 this widget in mm."""
743 return getint(
744 self.tk.call('winfo', 'screenmmwidth', self._w))
745 def winfo_screenvisual(self):
746 """Return one of the strings directcolor, grayscale, pseudocolor,
747 staticcolor, staticgray, or truecolor for the default
748 colormodel of this screen."""
749 return self.tk.call('winfo', 'screenvisual', self._w)
750 def winfo_screenwidth(self):
751 """Return the number of pixels of the width of the screen of
752 this widget in pixel."""
753 return getint(
754 self.tk.call('winfo', 'screenwidth', self._w))
755 def winfo_server(self):
756 """Return information of the X-Server of the screen of this widget in
757 the form "XmajorRminor vendor vendorVersion"."""
758 return self.tk.call('winfo', 'server', self._w)
759 def winfo_toplevel(self):
760 """Return the toplevel widget of this widget."""
761 return self._nametowidget(self.tk.call(
762 'winfo', 'toplevel', self._w))
763 def winfo_viewable(self):
764 """Return true if the widget and all its higher ancestors are mapped."""
765 return getint(
766 self.tk.call('winfo', 'viewable', self._w))
767 def winfo_visual(self):
768 """Return one of the strings directcolor, grayscale, pseudocolor,
769 staticcolor, staticgray, or truecolor for the
770 colormodel of this widget."""
771 return self.tk.call('winfo', 'visual', self._w)
772 def winfo_visualid(self):
773 """Return the X identifier for the visual for this widget."""
774 return self.tk.call('winfo', 'visualid', self._w)
775 def winfo_visualsavailable(self, includeids=0):
776 """Return a list of all visuals available for the screen
777 of this widget.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000778
Fredrik Lundh06d28152000-08-09 18:03:12 +0000779 Each item in the list consists of a visual name (see winfo_visual), a
780 depth and if INCLUDEIDS=1 is given also the X identifier."""
781 data = self.tk.split(
782 self.tk.call('winfo', 'visualsavailable', self._w,
783 includeids and 'includeids' or None))
Fredrik Lundh24037f72000-08-09 19:26:47 +0000784 if type(data) is StringType:
785 data = [self.tk.split(data)]
Fredrik Lundh06d28152000-08-09 18:03:12 +0000786 return map(self.__winfo_parseitem, data)
787 def __winfo_parseitem(self, t):
788 """Internal function."""
789 return t[:1] + tuple(map(self.__winfo_getint, t[1:]))
790 def __winfo_getint(self, x):
791 """Internal function."""
Eric S. Raymondfc170b12001-02-09 11:51:27 +0000792 return int(x, 0)
Fredrik Lundh06d28152000-08-09 18:03:12 +0000793 def winfo_vrootheight(self):
794 """Return the height of the virtual root window associated with this
795 widget in pixels. If there is no virtual root window return the
796 height of the screen."""
797 return getint(
798 self.tk.call('winfo', 'vrootheight', self._w))
799 def winfo_vrootwidth(self):
800 """Return the width of the virtual root window associated with this
801 widget in pixel. If there is no virtual root window return the
802 width of the screen."""
803 return getint(
804 self.tk.call('winfo', 'vrootwidth', self._w))
805 def winfo_vrootx(self):
806 """Return the x offset of the virtual root relative to the root
807 window of the screen of this widget."""
808 return getint(
809 self.tk.call('winfo', 'vrootx', self._w))
810 def winfo_vrooty(self):
811 """Return the y offset of the virtual root relative to the root
812 window of the screen of this widget."""
813 return getint(
814 self.tk.call('winfo', 'vrooty', self._w))
815 def winfo_width(self):
816 """Return the width of this widget."""
817 return getint(
818 self.tk.call('winfo', 'width', self._w))
819 def winfo_x(self):
820 """Return the x coordinate of the upper left corner of this widget
821 in the parent."""
822 return getint(
823 self.tk.call('winfo', 'x', self._w))
824 def winfo_y(self):
825 """Return the y coordinate of the upper left corner of this widget
826 in the parent."""
827 return getint(
828 self.tk.call('winfo', 'y', self._w))
829 def update(self):
830 """Enter event loop until all pending events have been processed by Tcl."""
831 self.tk.call('update')
832 def update_idletasks(self):
833 """Enter event loop until all idle callbacks have been called. This
834 will update the display of windows but not process events caused by
835 the user."""
836 self.tk.call('update', 'idletasks')
837 def bindtags(self, tagList=None):
838 """Set or get the list of bindtags for this widget.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000839
Fredrik Lundh06d28152000-08-09 18:03:12 +0000840 With no argument return the list of all bindtags associated with
841 this widget. With a list of strings as argument the bindtags are
842 set to this list. The bindtags determine in which order events are
843 processed (see bind)."""
844 if tagList is None:
845 return self.tk.splitlist(
846 self.tk.call('bindtags', self._w))
847 else:
848 self.tk.call('bindtags', self._w, tagList)
849 def _bind(self, what, sequence, func, add, needcleanup=1):
850 """Internal function."""
851 if type(func) is StringType:
852 self.tk.call(what + (sequence, func))
853 elif func:
854 funcid = self._register(func, self._substitute,
855 needcleanup)
856 cmd = ('%sif {"[%s %s]" == "break"} break\n'
857 %
858 (add and '+' or '',
Martin v. Löwisc8718c12001-08-09 16:57:33 +0000859 funcid, self._subst_format_str))
Fredrik Lundh06d28152000-08-09 18:03:12 +0000860 self.tk.call(what + (sequence, cmd))
861 return funcid
862 elif sequence:
863 return self.tk.call(what + (sequence,))
864 else:
865 return self.tk.splitlist(self.tk.call(what))
866 def bind(self, sequence=None, func=None, add=None):
867 """Bind to this widget at event SEQUENCE a call to function FUNC.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000868
Fredrik Lundh06d28152000-08-09 18:03:12 +0000869 SEQUENCE is a string of concatenated event
870 patterns. An event pattern is of the form
871 <MODIFIER-MODIFIER-TYPE-DETAIL> where MODIFIER is one
872 of Control, Mod2, M2, Shift, Mod3, M3, Lock, Mod4, M4,
873 Button1, B1, Mod5, M5 Button2, B2, Meta, M, Button3,
874 B3, Alt, Button4, B4, Double, Button5, B5 Triple,
875 Mod1, M1. TYPE is one of Activate, Enter, Map,
876 ButtonPress, Button, Expose, Motion, ButtonRelease
877 FocusIn, MouseWheel, Circulate, FocusOut, Property,
878 Colormap, Gravity Reparent, Configure, KeyPress, Key,
879 Unmap, Deactivate, KeyRelease Visibility, Destroy,
880 Leave and DETAIL is the button number for ButtonPress,
881 ButtonRelease and DETAIL is the Keysym for KeyPress and
882 KeyRelease. Examples are
883 <Control-Button-1> for pressing Control and mouse button 1 or
884 <Alt-A> for pressing A and the Alt key (KeyPress can be omitted).
885 An event pattern can also be a virtual event of the form
886 <<AString>> where AString can be arbitrary. This
887 event can be generated by event_generate.
888 If events are concatenated they must appear shortly
889 after each other.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000890
Fredrik Lundh06d28152000-08-09 18:03:12 +0000891 FUNC will be called if the event sequence occurs with an
892 instance of Event as argument. If the return value of FUNC is
893 "break" no further bound function is invoked.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000894
Fredrik Lundh06d28152000-08-09 18:03:12 +0000895 An additional boolean parameter ADD specifies whether FUNC will
896 be called additionally to the other bound function or whether
897 it will replace the previous function.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000898
Fredrik Lundh06d28152000-08-09 18:03:12 +0000899 Bind will return an identifier to allow deletion of the bound function with
900 unbind without memory leak.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000901
Fredrik Lundh06d28152000-08-09 18:03:12 +0000902 If FUNC or SEQUENCE is omitted the bound function or list
903 of bound events are returned."""
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000904
Fredrik Lundh06d28152000-08-09 18:03:12 +0000905 return self._bind(('bind', self._w), sequence, func, add)
906 def unbind(self, sequence, funcid=None):
907 """Unbind for this widget for event SEQUENCE the
908 function identified with FUNCID."""
909 self.tk.call('bind', self._w, sequence, '')
910 if funcid:
911 self.deletecommand(funcid)
912 def bind_all(self, sequence=None, func=None, add=None):
913 """Bind to all widgets at an event SEQUENCE a call to function FUNC.
914 An additional boolean parameter ADD specifies whether FUNC will
915 be called additionally to the other bound function or whether
916 it will replace the previous function. See bind for the return value."""
917 return self._bind(('bind', 'all'), sequence, func, add, 0)
918 def unbind_all(self, sequence):
919 """Unbind for all widgets for event SEQUENCE all functions."""
920 self.tk.call('bind', 'all' , sequence, '')
921 def bind_class(self, className, sequence=None, func=None, add=None):
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000922
Fredrik Lundh06d28152000-08-09 18:03:12 +0000923 """Bind to widgets with bindtag CLASSNAME at event
924 SEQUENCE a call of function FUNC. An additional
925 boolean parameter ADD specifies whether FUNC will be
926 called additionally to the other bound function or
927 whether it will replace the previous function. See bind for
928 the return value."""
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000929
Fredrik Lundh06d28152000-08-09 18:03:12 +0000930 return self._bind(('bind', className), sequence, func, add, 0)
931 def unbind_class(self, className, sequence):
932 """Unbind for a all widgets with bindtag CLASSNAME for event SEQUENCE
933 all functions."""
934 self.tk.call('bind', className , sequence, '')
935 def mainloop(self, n=0):
936 """Call the mainloop of Tk."""
937 self.tk.mainloop(n)
938 def quit(self):
939 """Quit the Tcl interpreter. All widgets will be destroyed."""
940 self.tk.quit()
941 def _getints(self, string):
942 """Internal function."""
943 if string:
944 return tuple(map(getint, self.tk.splitlist(string)))
945 def _getdoubles(self, string):
946 """Internal function."""
947 if string:
948 return tuple(map(getdouble, self.tk.splitlist(string)))
949 def _getboolean(self, string):
950 """Internal function."""
951 if string:
952 return self.tk.getboolean(string)
953 def _displayof(self, displayof):
954 """Internal function."""
955 if displayof:
956 return ('-displayof', displayof)
957 if displayof is None:
958 return ('-displayof', self._w)
959 return ()
960 def _options(self, cnf, kw = None):
961 """Internal function."""
962 if kw:
963 cnf = _cnfmerge((cnf, kw))
964 else:
965 cnf = _cnfmerge(cnf)
966 res = ()
967 for k, v in cnf.items():
968 if v is not None:
969 if k[-1] == '_': k = k[:-1]
970 if callable(v):
971 v = self._register(v)
972 res = res + ('-'+k, v)
973 return res
974 def nametowidget(self, name):
975 """Return the Tkinter instance of a widget identified by
976 its Tcl name NAME."""
977 w = self
978 if name[0] == '.':
979 w = w._root()
980 name = name[1:]
Fredrik Lundh06d28152000-08-09 18:03:12 +0000981 while name:
Eric S. Raymondfc170b12001-02-09 11:51:27 +0000982 i = name.find('.')
Fredrik Lundh06d28152000-08-09 18:03:12 +0000983 if i >= 0:
984 name, tail = name[:i], name[i+1:]
985 else:
986 tail = ''
987 w = w.children[name]
988 name = tail
989 return w
990 _nametowidget = nametowidget
991 def _register(self, func, subst=None, needcleanup=1):
992 """Return a newly created Tcl function. If this
993 function is called, the Python function FUNC will
994 be executed. An optional function SUBST can
995 be given which will be executed before FUNC."""
996 f = CallWrapper(func, subst, self).__call__
997 name = `id(f)`
998 try:
999 func = func.im_func
1000 except AttributeError:
1001 pass
1002 try:
1003 name = name + func.__name__
1004 except AttributeError:
1005 pass
1006 self.tk.createcommand(name, f)
1007 if needcleanup:
1008 if self._tclCommands is None:
1009 self._tclCommands = []
1010 self._tclCommands.append(name)
1011 #print '+ Tkinter created command', name
1012 return name
1013 register = _register
1014 def _root(self):
1015 """Internal function."""
1016 w = self
1017 while w.master: w = w.master
1018 return w
1019 _subst_format = ('%#', '%b', '%f', '%h', '%k',
1020 '%s', '%t', '%w', '%x', '%y',
1021 '%A', '%E', '%K', '%N', '%W', '%T', '%X', '%Y', '%D')
Martin v. Löwisc8718c12001-08-09 16:57:33 +00001022 _subst_format_str = " ".join(_subst_format)
Fredrik Lundh06d28152000-08-09 18:03:12 +00001023 def _substitute(self, *args):
1024 """Internal function."""
1025 if len(args) != len(self._subst_format): return args
1026 getboolean = self.tk.getboolean
1027 getint = int
1028 nsign, b, f, h, k, s, t, w, x, y, A, E, K, N, W, T, X, Y, D = args
1029 # Missing: (a, c, d, m, o, v, B, R)
1030 e = Event()
1031 e.serial = getint(nsign)
1032 e.num = getint(b)
1033 try: e.focus = getboolean(f)
1034 except TclError: pass
1035 e.height = getint(h)
1036 e.keycode = getint(k)
1037 # For Visibility events, event state is a string and
1038 # not an integer:
1039 try:
1040 e.state = getint(s)
1041 except ValueError:
1042 e.state = s
1043 e.time = getint(t)
1044 e.width = getint(w)
1045 e.x = getint(x)
1046 e.y = getint(y)
1047 e.char = A
1048 try: e.send_event = getboolean(E)
1049 except TclError: pass
1050 e.keysym = K
1051 e.keysym_num = getint(N)
1052 e.type = T
1053 try:
1054 e.widget = self._nametowidget(W)
1055 except KeyError:
1056 e.widget = W
1057 e.x_root = getint(X)
1058 e.y_root = getint(Y)
Fredrik Lundha249f162000-09-07 15:05:09 +00001059 try:
1060 e.delta = getint(D)
1061 except ValueError:
1062 e.delta = 0
Fredrik Lundh06d28152000-08-09 18:03:12 +00001063 return (e,)
1064 def _report_exception(self):
1065 """Internal function."""
1066 import sys
1067 exc, val, tb = sys.exc_type, sys.exc_value, sys.exc_traceback
1068 root = self._root()
1069 root.report_callback_exception(exc, val, tb)
1070 # These used to be defined in Widget:
1071 def configure(self, cnf=None, **kw):
1072 """Configure resources of a widget.
Barry Warsaw107e6231998-12-15 00:44:15 +00001073
Fredrik Lundh06d28152000-08-09 18:03:12 +00001074 The values for resources are specified as keyword
1075 arguments. To get an overview about
1076 the allowed keyword arguments call the method keys.
1077 """
1078 # XXX ought to generalize this so tag_config etc. can use it
1079 if kw:
1080 cnf = _cnfmerge((cnf, kw))
1081 elif cnf:
1082 cnf = _cnfmerge(cnf)
1083 if cnf is None:
1084 cnf = {}
1085 for x in self.tk.split(
1086 self.tk.call(self._w, 'configure')):
1087 cnf[x[0][1:]] = (x[0][1:],) + x[1:]
1088 return cnf
1089 if type(cnf) is StringType:
1090 x = self.tk.split(self.tk.call(
1091 self._w, 'configure', '-'+cnf))
1092 return (x[0][1:],) + x[1:]
1093 self.tk.call((self._w, 'configure')
1094 + self._options(cnf))
1095 config = configure
1096 def cget(self, key):
1097 """Return the resource value for a KEY given as string."""
1098 return self.tk.call(self._w, 'cget', '-' + key)
1099 __getitem__ = cget
1100 def __setitem__(self, key, value):
1101 self.configure({key: value})
1102 def keys(self):
1103 """Return a list of all resource names of this widget."""
1104 return map(lambda x: x[0][1:],
1105 self.tk.split(self.tk.call(self._w, 'configure')))
1106 def __str__(self):
1107 """Return the window path name of this widget."""
1108 return self._w
1109 # Pack methods that apply to the master
1110 _noarg_ = ['_noarg_']
1111 def pack_propagate(self, flag=_noarg_):
1112 """Set or get the status for propagation of geometry information.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001113
Fredrik Lundh06d28152000-08-09 18:03:12 +00001114 A boolean argument specifies whether the geometry information
1115 of the slaves will determine the size of this widget. If no argument
1116 is given the current setting will be returned.
1117 """
1118 if flag is Misc._noarg_:
1119 return self._getboolean(self.tk.call(
1120 'pack', 'propagate', self._w))
1121 else:
1122 self.tk.call('pack', 'propagate', self._w, flag)
1123 propagate = pack_propagate
1124 def pack_slaves(self):
1125 """Return a list of all slaves of this widget
1126 in its packing order."""
1127 return map(self._nametowidget,
1128 self.tk.splitlist(
1129 self.tk.call('pack', 'slaves', self._w)))
1130 slaves = pack_slaves
1131 # Place method that applies to the master
1132 def place_slaves(self):
1133 """Return a list of all slaves of this widget
1134 in its packing order."""
1135 return map(self._nametowidget,
1136 self.tk.splitlist(
1137 self.tk.call(
1138 'place', 'slaves', self._w)))
1139 # Grid methods that apply to the master
1140 def grid_bbox(self, column=None, row=None, col2=None, row2=None):
1141 """Return a tuple of integer coordinates for the bounding
1142 box of this widget controlled by the geometry manager grid.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001143
Fredrik Lundh06d28152000-08-09 18:03:12 +00001144 If COLUMN, ROW is given the bounding box applies from
1145 the cell with row and column 0 to the specified
1146 cell. If COL2 and ROW2 are given the bounding box
1147 starts at that cell.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001148
Fredrik Lundh06d28152000-08-09 18:03:12 +00001149 The returned integers specify the offset of the upper left
1150 corner in the master widget and the width and height.
1151 """
1152 args = ('grid', 'bbox', self._w)
1153 if column is not None and row is not None:
1154 args = args + (column, row)
1155 if col2 is not None and row2 is not None:
1156 args = args + (col2, row2)
1157 return self._getints(apply(self.tk.call, args)) or None
Guido van Rossum18468821994-06-20 07:49:28 +00001158
Fredrik Lundh06d28152000-08-09 18:03:12 +00001159 bbox = grid_bbox
1160 def _grid_configure(self, command, index, cnf, kw):
1161 """Internal function."""
1162 if type(cnf) is StringType and not kw:
1163 if cnf[-1:] == '_':
1164 cnf = cnf[:-1]
1165 if cnf[:1] != '-':
1166 cnf = '-'+cnf
1167 options = (cnf,)
1168 else:
1169 options = self._options(cnf, kw)
1170 if not options:
1171 res = self.tk.call('grid',
1172 command, self._w, index)
1173 words = self.tk.splitlist(res)
1174 dict = {}
1175 for i in range(0, len(words), 2):
1176 key = words[i][1:]
1177 value = words[i+1]
1178 if not value:
1179 value = None
1180 elif '.' in value:
1181 value = getdouble(value)
1182 else:
1183 value = getint(value)
1184 dict[key] = value
1185 return dict
1186 res = self.tk.call(
1187 ('grid', command, self._w, index)
1188 + options)
1189 if len(options) == 1:
1190 if not res: return None
1191 # In Tk 7.5, -width can be a float
1192 if '.' in res: return getdouble(res)
1193 return getint(res)
1194 def grid_columnconfigure(self, index, cnf={}, **kw):
1195 """Configure column INDEX of a grid.
Guido van Rossum80f8be81997-12-02 19:51:39 +00001196
Fredrik Lundh06d28152000-08-09 18:03:12 +00001197 Valid resources are minsize (minimum size of the column),
1198 weight (how much does additional space propagate to this column)
1199 and pad (how much space to let additionally)."""
1200 return self._grid_configure('columnconfigure', index, cnf, kw)
1201 columnconfigure = grid_columnconfigure
Martin v. Löwisdc579092001-10-13 09:33:51 +00001202 def grid_location(self, x, y):
1203 """Return a tuple of column and row which identify the cell
1204 at which the pixel at position X and Y inside the master
1205 widget is located."""
1206 return self._getints(
1207 self.tk.call(
1208 'grid', 'location', self._w, x, y)) or None
Fredrik Lundh06d28152000-08-09 18:03:12 +00001209 def grid_propagate(self, flag=_noarg_):
1210 """Set or get the status for propagation of geometry information.
Guido van Rossum80f8be81997-12-02 19:51:39 +00001211
Fredrik Lundh06d28152000-08-09 18:03:12 +00001212 A boolean argument specifies whether the geometry information
1213 of the slaves will determine the size of this widget. If no argument
1214 is given, the current setting will be returned.
1215 """
1216 if flag is Misc._noarg_:
1217 return self._getboolean(self.tk.call(
1218 'grid', 'propagate', self._w))
1219 else:
1220 self.tk.call('grid', 'propagate', self._w, flag)
1221 def grid_rowconfigure(self, index, cnf={}, **kw):
1222 """Configure row INDEX of a grid.
Guido van Rossum80f8be81997-12-02 19:51:39 +00001223
Fredrik Lundh06d28152000-08-09 18:03:12 +00001224 Valid resources are minsize (minimum size of the row),
1225 weight (how much does additional space propagate to this row)
1226 and pad (how much space to let additionally)."""
1227 return self._grid_configure('rowconfigure', index, cnf, kw)
1228 rowconfigure = grid_rowconfigure
1229 def grid_size(self):
1230 """Return a tuple of the number of column and rows in the grid."""
1231 return self._getints(
1232 self.tk.call('grid', 'size', self._w)) or None
1233 size = grid_size
1234 def grid_slaves(self, row=None, column=None):
1235 """Return a list of all slaves of this widget
1236 in its packing order."""
1237 args = ()
1238 if row is not None:
1239 args = args + ('-row', row)
1240 if column is not None:
1241 args = args + ('-column', column)
1242 return map(self._nametowidget,
1243 self.tk.splitlist(self.tk.call(
1244 ('grid', 'slaves', self._w) + args)))
Guido van Rossum80f8be81997-12-02 19:51:39 +00001245
Fredrik Lundh06d28152000-08-09 18:03:12 +00001246 # Support for the "event" command, new in Tk 4.2.
1247 # By Case Roole.
Guido van Rossum80f8be81997-12-02 19:51:39 +00001248
Fredrik Lundh06d28152000-08-09 18:03:12 +00001249 def event_add(self, virtual, *sequences):
1250 """Bind a virtual event VIRTUAL (of the form <<Name>>)
1251 to an event SEQUENCE such that the virtual event is triggered
1252 whenever SEQUENCE occurs."""
1253 args = ('event', 'add', virtual) + sequences
1254 self.tk.call(args)
Guido van Rossumc2966511998-04-10 19:16:10 +00001255
Fredrik Lundh06d28152000-08-09 18:03:12 +00001256 def event_delete(self, virtual, *sequences):
1257 """Unbind a virtual event VIRTUAL from SEQUENCE."""
1258 args = ('event', 'delete', virtual) + sequences
1259 self.tk.call(args)
Guido van Rossumc2966511998-04-10 19:16:10 +00001260
Fredrik Lundh06d28152000-08-09 18:03:12 +00001261 def event_generate(self, sequence, **kw):
1262 """Generate an event SEQUENCE. Additional
1263 keyword arguments specify parameter of the event
1264 (e.g. x, y, rootx, rooty)."""
1265 args = ('event', 'generate', self._w, sequence)
1266 for k, v in kw.items():
1267 args = args + ('-%s' % k, str(v))
1268 self.tk.call(args)
1269
1270 def event_info(self, virtual=None):
1271 """Return a list of all virtual events or the information
1272 about the SEQUENCE bound to the virtual event VIRTUAL."""
1273 return self.tk.splitlist(
1274 self.tk.call('event', 'info', virtual))
1275
1276 # Image related commands
1277
1278 def image_names(self):
1279 """Return a list of all existing image names."""
1280 return self.tk.call('image', 'names')
1281
1282 def image_types(self):
1283 """Return a list of all available image types (e.g. phote bitmap)."""
1284 return self.tk.call('image', 'types')
Guido van Rossumc2966511998-04-10 19:16:10 +00001285
Guido van Rossum80f8be81997-12-02 19:51:39 +00001286
Guido van Rossuma5773dd1995-09-07 19:22:00 +00001287class CallWrapper:
Fredrik Lundh06d28152000-08-09 18:03:12 +00001288 """Internal class. Stores function to call when some user
1289 defined Tcl function is called e.g. after an event occurred."""
1290 def __init__(self, func, subst, widget):
1291 """Store FUNC, SUBST and WIDGET as members."""
1292 self.func = func
1293 self.subst = subst
1294 self.widget = widget
1295 def __call__(self, *args):
1296 """Apply first function SUBST to arguments, than FUNC."""
1297 try:
1298 if self.subst:
1299 args = apply(self.subst, args)
1300 return apply(self.func, args)
1301 except SystemExit, msg:
1302 raise SystemExit, msg
1303 except:
1304 self.widget._report_exception()
Guido van Rossum18468821994-06-20 07:49:28 +00001305
Guido van Rossume365a591998-05-01 19:48:20 +00001306
Guido van Rossum18468821994-06-20 07:49:28 +00001307class Wm:
Fredrik Lundh06d28152000-08-09 18:03:12 +00001308 """Provides functions for the communication with the window manager."""
1309 def wm_aspect(self,
1310 minNumer=None, minDenom=None,
1311 maxNumer=None, maxDenom=None):
1312 """Instruct the window manager to set the aspect ratio (width/height)
1313 of this widget to be between MINNUMER/MINDENOM and MAXNUMER/MAXDENOM. Return a tuple
1314 of the actual values if no argument is given."""
1315 return self._getints(
1316 self.tk.call('wm', 'aspect', self._w,
1317 minNumer, minDenom,
1318 maxNumer, maxDenom))
1319 aspect = wm_aspect
1320 def wm_client(self, name=None):
1321 """Store NAME in WM_CLIENT_MACHINE property of this widget. Return
1322 current value."""
1323 return self.tk.call('wm', 'client', self._w, name)
1324 client = wm_client
1325 def wm_colormapwindows(self, *wlist):
1326 """Store list of window names (WLIST) into WM_COLORMAPWINDOWS property
1327 of this widget. This list contains windows whose colormaps differ from their
1328 parents. Return current list of widgets if WLIST is empty."""
1329 if len(wlist) > 1:
1330 wlist = (wlist,) # Tk needs a list of windows here
1331 args = ('wm', 'colormapwindows', self._w) + wlist
1332 return map(self._nametowidget, self.tk.call(args))
1333 colormapwindows = wm_colormapwindows
1334 def wm_command(self, value=None):
1335 """Store VALUE in WM_COMMAND property. It is the command
1336 which shall be used to invoke the application. Return current
1337 command if VALUE is None."""
1338 return self.tk.call('wm', 'command', self._w, value)
1339 command = wm_command
1340 def wm_deiconify(self):
1341 """Deiconify this widget. If it was never mapped it will not be mapped.
1342 On Windows it will raise this widget and give it the focus."""
1343 return self.tk.call('wm', 'deiconify', self._w)
1344 deiconify = wm_deiconify
1345 def wm_focusmodel(self, model=None):
1346 """Set focus model to MODEL. "active" means that this widget will claim
1347 the focus itself, "passive" means that the window manager shall give
1348 the focus. Return current focus model if MODEL is None."""
1349 return self.tk.call('wm', 'focusmodel', self._w, model)
1350 focusmodel = wm_focusmodel
1351 def wm_frame(self):
1352 """Return identifier for decorative frame of this widget if present."""
1353 return self.tk.call('wm', 'frame', self._w)
1354 frame = wm_frame
1355 def wm_geometry(self, newGeometry=None):
1356 """Set geometry to NEWGEOMETRY of the form =widthxheight+x+y. Return
1357 current value if None is given."""
1358 return self.tk.call('wm', 'geometry', self._w, newGeometry)
1359 geometry = wm_geometry
1360 def wm_grid(self,
1361 baseWidth=None, baseHeight=None,
1362 widthInc=None, heightInc=None):
1363 """Instruct the window manager that this widget shall only be
1364 resized on grid boundaries. WIDTHINC and HEIGHTINC are the width and
1365 height of a grid unit in pixels. BASEWIDTH and BASEHEIGHT are the
1366 number of grid units requested in Tk_GeometryRequest."""
1367 return self._getints(self.tk.call(
1368 'wm', 'grid', self._w,
1369 baseWidth, baseHeight, widthInc, heightInc))
1370 grid = wm_grid
1371 def wm_group(self, pathName=None):
1372 """Set the group leader widgets for related widgets to PATHNAME. Return
1373 the group leader of this widget if None is given."""
1374 return self.tk.call('wm', 'group', self._w, pathName)
1375 group = wm_group
1376 def wm_iconbitmap(self, bitmap=None):
1377 """Set bitmap for the iconified widget to BITMAP. Return
1378 the bitmap if None is given."""
1379 return self.tk.call('wm', 'iconbitmap', self._w, bitmap)
1380 iconbitmap = wm_iconbitmap
1381 def wm_iconify(self):
1382 """Display widget as icon."""
1383 return self.tk.call('wm', 'iconify', self._w)
1384 iconify = wm_iconify
1385 def wm_iconmask(self, bitmap=None):
1386 """Set mask for the icon bitmap of this widget. Return the
1387 mask if None is given."""
1388 return self.tk.call('wm', 'iconmask', self._w, bitmap)
1389 iconmask = wm_iconmask
1390 def wm_iconname(self, newName=None):
1391 """Set the name of the icon for this widget. Return the name if
1392 None is given."""
1393 return self.tk.call('wm', 'iconname', self._w, newName)
1394 iconname = wm_iconname
1395 def wm_iconposition(self, x=None, y=None):
1396 """Set the position of the icon of this widget to X and Y. Return
1397 a tuple of the current values of X and X if None is given."""
1398 return self._getints(self.tk.call(
1399 'wm', 'iconposition', self._w, x, y))
1400 iconposition = wm_iconposition
1401 def wm_iconwindow(self, pathName=None):
1402 """Set widget PATHNAME to be displayed instead of icon. Return the current
1403 value if None is given."""
1404 return self.tk.call('wm', 'iconwindow', self._w, pathName)
1405 iconwindow = wm_iconwindow
1406 def wm_maxsize(self, width=None, height=None):
1407 """Set max WIDTH and HEIGHT for this widget. If the window is gridded
1408 the values are given in grid units. Return the current values if None
1409 is given."""
1410 return self._getints(self.tk.call(
1411 'wm', 'maxsize', self._w, width, height))
1412 maxsize = wm_maxsize
1413 def wm_minsize(self, width=None, height=None):
1414 """Set min WIDTH and HEIGHT for this widget. If the window is gridded
1415 the values are given in grid units. Return the current values if None
1416 is given."""
1417 return self._getints(self.tk.call(
1418 'wm', 'minsize', self._w, width, height))
1419 minsize = wm_minsize
1420 def wm_overrideredirect(self, boolean=None):
1421 """Instruct the window manager to ignore this widget
1422 if BOOLEAN is given with 1. Return the current value if None
1423 is given."""
1424 return self._getboolean(self.tk.call(
1425 'wm', 'overrideredirect', self._w, boolean))
1426 overrideredirect = wm_overrideredirect
1427 def wm_positionfrom(self, who=None):
1428 """Instruct the window manager that the position of this widget shall
1429 be defined by the user if WHO is "user", and by its own policy if WHO is
1430 "program"."""
1431 return self.tk.call('wm', 'positionfrom', self._w, who)
1432 positionfrom = wm_positionfrom
1433 def wm_protocol(self, name=None, func=None):
1434 """Bind function FUNC to command NAME for this widget.
1435 Return the function bound to NAME if None is given. NAME could be
1436 e.g. "WM_SAVE_YOURSELF" or "WM_DELETE_WINDOW"."""
1437 if callable(func):
1438 command = self._register(func)
1439 else:
1440 command = func
1441 return self.tk.call(
1442 'wm', 'protocol', self._w, name, command)
1443 protocol = wm_protocol
1444 def wm_resizable(self, width=None, height=None):
1445 """Instruct the window manager whether this width can be resized
1446 in WIDTH or HEIGHT. Both values are boolean values."""
1447 return self.tk.call('wm', 'resizable', self._w, width, height)
1448 resizable = wm_resizable
1449 def wm_sizefrom(self, who=None):
1450 """Instruct the window manager that the size of this widget shall
1451 be defined by the user if WHO is "user", and by its own policy if WHO is
1452 "program"."""
1453 return self.tk.call('wm', 'sizefrom', self._w, who)
1454 sizefrom = wm_sizefrom
Fredrik Lundh289ad8f2000-08-09 19:11:59 +00001455 def wm_state(self, newstate=None):
1456 """Query or set the state of this widget as one of normal, icon,
1457 iconic (see wm_iconwindow), withdrawn, or zoomed (Windows only)."""
1458 return self.tk.call('wm', 'state', self._w, newstate)
Fredrik Lundh06d28152000-08-09 18:03:12 +00001459 state = wm_state
1460 def wm_title(self, string=None):
1461 """Set the title of this widget."""
1462 return self.tk.call('wm', 'title', self._w, string)
1463 title = wm_title
1464 def wm_transient(self, master=None):
1465 """Instruct the window manager that this widget is transient
1466 with regard to widget MASTER."""
1467 return self.tk.call('wm', 'transient', self._w, master)
1468 transient = wm_transient
1469 def wm_withdraw(self):
1470 """Withdraw this widget from the screen such that it is unmapped
1471 and forgotten by the window manager. Re-draw it with wm_deiconify."""
1472 return self.tk.call('wm', 'withdraw', self._w)
1473 withdraw = wm_withdraw
Guido van Rossume365a591998-05-01 19:48:20 +00001474
Guido van Rossum18468821994-06-20 07:49:28 +00001475
1476class Tk(Misc, Wm):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001477 """Toplevel widget of Tk which represents mostly the main window
1478 of an appliation. It has an associated Tcl interpreter."""
1479 _w = '.'
1480 def __init__(self, screenName=None, baseName=None, className='Tk'):
1481 """Return a new Toplevel widget on screen SCREENNAME. A new Tcl interpreter will
1482 be created. BASENAME will be used for the identification of the profile file (see
1483 readprofile).
1484 It is constructed from sys.argv[0] without extensions if None is given. CLASSNAME
1485 is the name of the widget class."""
1486 global _default_root
1487 self.master = None
1488 self.children = {}
1489 if baseName is None:
1490 import sys, os
1491 baseName = os.path.basename(sys.argv[0])
1492 baseName, ext = os.path.splitext(baseName)
1493 if ext not in ('.py', '.pyc', '.pyo'):
1494 baseName = baseName + ext
1495 self.tk = _tkinter.create(screenName, baseName, className)
Jack Jansenbe92af02001-08-23 13:25:59 +00001496 if _MacOS and hasattr(_MacOS, 'SchedParams'):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001497 # Disable event scanning except for Command-Period
1498 _MacOS.SchedParams(1, 0)
1499 # Work around nasty MacTk bug
1500 # XXX Is this one still needed?
1501 self.update()
1502 # Version sanity checks
1503 tk_version = self.tk.getvar('tk_version')
1504 if tk_version != _tkinter.TK_VERSION:
1505 raise RuntimeError, \
1506 "tk.h version (%s) doesn't match libtk.a version (%s)" \
1507 % (_tkinter.TK_VERSION, tk_version)
1508 tcl_version = self.tk.getvar('tcl_version')
1509 if tcl_version != _tkinter.TCL_VERSION:
1510 raise RuntimeError, \
1511 "tcl.h version (%s) doesn't match libtcl.a version (%s)" \
1512 % (_tkinter.TCL_VERSION, tcl_version)
1513 if TkVersion < 4.0:
1514 raise RuntimeError, \
1515 "Tk 4.0 or higher is required; found Tk %s" \
1516 % str(TkVersion)
1517 self.tk.createcommand('tkerror', _tkerror)
1518 self.tk.createcommand('exit', _exit)
1519 self.readprofile(baseName, className)
1520 if _support_default_root and not _default_root:
1521 _default_root = self
1522 self.protocol("WM_DELETE_WINDOW", self.destroy)
1523 def destroy(self):
1524 """Destroy this and all descendants widgets. This will
1525 end the application of this Tcl interpreter."""
1526 for c in self.children.values(): c.destroy()
1527 self.tk.call('destroy', self._w)
1528 Misc.destroy(self)
1529 global _default_root
1530 if _support_default_root and _default_root is self:
1531 _default_root = None
1532 def readprofile(self, baseName, className):
1533 """Internal function. It reads BASENAME.tcl and CLASSNAME.tcl into
1534 the Tcl Interpreter and calls execfile on BASENAME.py and CLASSNAME.py if
1535 such a file exists in the home directory."""
1536 import os
1537 if os.environ.has_key('HOME'): home = os.environ['HOME']
1538 else: home = os.curdir
1539 class_tcl = os.path.join(home, '.%s.tcl' % className)
1540 class_py = os.path.join(home, '.%s.py' % className)
1541 base_tcl = os.path.join(home, '.%s.tcl' % baseName)
1542 base_py = os.path.join(home, '.%s.py' % baseName)
1543 dir = {'self': self}
1544 exec 'from Tkinter import *' in dir
1545 if os.path.isfile(class_tcl):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001546 self.tk.call('source', class_tcl)
1547 if os.path.isfile(class_py):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001548 execfile(class_py, dir)
1549 if os.path.isfile(base_tcl):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001550 self.tk.call('source', base_tcl)
1551 if os.path.isfile(base_py):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001552 execfile(base_py, dir)
1553 def report_callback_exception(self, exc, val, tb):
1554 """Internal function. It reports exception on sys.stderr."""
1555 import traceback, sys
1556 sys.stderr.write("Exception in Tkinter callback\n")
1557 sys.last_type = exc
1558 sys.last_value = val
1559 sys.last_traceback = tb
1560 traceback.print_exception(exc, val, tb)
Guido van Rossum18468821994-06-20 07:49:28 +00001561
Guido van Rossum368e06b1997-11-07 20:38:49 +00001562# Ideally, the classes Pack, Place and Grid disappear, the
1563# pack/place/grid methods are defined on the Widget class, and
1564# everybody uses w.pack_whatever(...) instead of Pack.whatever(w,
1565# ...), with pack(), place() and grid() being short for
1566# pack_configure(), place_configure() and grid_columnconfigure(), and
1567# forget() being short for pack_forget(). As a practical matter, I'm
1568# afraid that there is too much code out there that may be using the
1569# Pack, Place or Grid class, so I leave them intact -- but only as
1570# backwards compatibility features. Also note that those methods that
1571# take a master as argument (e.g. pack_propagate) have been moved to
1572# the Misc class (which now incorporates all methods common between
1573# toplevel and interior widgets). Again, for compatibility, these are
1574# copied into the Pack, Place or Grid class.
1575
Guido van Rossum18468821994-06-20 07:49:28 +00001576class Pack:
Fredrik Lundh06d28152000-08-09 18:03:12 +00001577 """Geometry manager Pack.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001578
Fredrik Lundh06d28152000-08-09 18:03:12 +00001579 Base class to use the methods pack_* in every widget."""
1580 def pack_configure(self, cnf={}, **kw):
1581 """Pack a widget in the parent widget. Use as options:
1582 after=widget - pack it after you have packed widget
1583 anchor=NSEW (or subset) - position widget according to
1584 given direction
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001585 before=widget - pack it before you will pack widget
Fredrik Lundh06d28152000-08-09 18:03:12 +00001586 expand=1 or 0 - expand widget if parent size grows
1587 fill=NONE or X or Y or BOTH - fill widget if widget grows
1588 in=master - use master to contain this widget
1589 ipadx=amount - add internal padding in x direction
1590 ipady=amount - add internal padding in y direction
1591 padx=amount - add padding in x direction
1592 pady=amount - add padding in y direction
1593 side=TOP or BOTTOM or LEFT or RIGHT - where to add this widget.
1594 """
1595 self.tk.call(
1596 ('pack', 'configure', self._w)
1597 + self._options(cnf, kw))
1598 pack = configure = config = pack_configure
1599 def pack_forget(self):
1600 """Unmap this widget and do not use it for the packing order."""
1601 self.tk.call('pack', 'forget', self._w)
1602 forget = pack_forget
1603 def pack_info(self):
1604 """Return information about the packing options
1605 for this widget."""
1606 words = self.tk.splitlist(
1607 self.tk.call('pack', 'info', self._w))
1608 dict = {}
1609 for i in range(0, len(words), 2):
1610 key = words[i][1:]
1611 value = words[i+1]
1612 if value[:1] == '.':
1613 value = self._nametowidget(value)
1614 dict[key] = value
1615 return dict
1616 info = pack_info
1617 propagate = pack_propagate = Misc.pack_propagate
1618 slaves = pack_slaves = Misc.pack_slaves
Guido van Rossum18468821994-06-20 07:49:28 +00001619
1620class Place:
Fredrik Lundh06d28152000-08-09 18:03:12 +00001621 """Geometry manager Place.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001622
Fredrik Lundh06d28152000-08-09 18:03:12 +00001623 Base class to use the methods place_* in every widget."""
1624 def place_configure(self, cnf={}, **kw):
1625 """Place a widget in the parent widget. Use as options:
1626 in=master - master relative to which the widget is placed.
1627 x=amount - locate anchor of this widget at position x of master
1628 y=amount - locate anchor of this widget at position y of master
1629 relx=amount - locate anchor of this widget between 0.0 and 1.0
1630 relative to width of master (1.0 is right edge)
1631 rely=amount - locate anchor of this widget between 0.0 and 1.0
1632 relative to height of master (1.0 is bottom edge)
1633 anchor=NSEW (or subset) - position anchor according to given direction
1634 width=amount - width of this widget in pixel
1635 height=amount - height of this widget in pixel
1636 relwidth=amount - width of this widget between 0.0 and 1.0
1637 relative to width of master (1.0 is the same width
1638 as the master)
1639 relheight=amount - height of this widget between 0.0 and 1.0
1640 relative to height of master (1.0 is the same
1641 height as the master)
1642 bordermode="inside" or "outside" - whether to take border width of master widget
1643 into account
1644 """
1645 for k in ['in_']:
1646 if kw.has_key(k):
1647 kw[k[:-1]] = kw[k]
1648 del kw[k]
1649 self.tk.call(
1650 ('place', 'configure', self._w)
1651 + self._options(cnf, kw))
1652 place = configure = config = place_configure
1653 def place_forget(self):
1654 """Unmap this widget."""
1655 self.tk.call('place', 'forget', self._w)
1656 forget = place_forget
1657 def place_info(self):
1658 """Return information about the placing options
1659 for this widget."""
1660 words = self.tk.splitlist(
1661 self.tk.call('place', 'info', self._w))
1662 dict = {}
1663 for i in range(0, len(words), 2):
1664 key = words[i][1:]
1665 value = words[i+1]
1666 if value[:1] == '.':
1667 value = self._nametowidget(value)
1668 dict[key] = value
1669 return dict
1670 info = place_info
1671 slaves = place_slaves = Misc.place_slaves
Guido van Rossum18468821994-06-20 07:49:28 +00001672
Guido van Rossum37dcab11996-05-16 16:00:19 +00001673class Grid:
Fredrik Lundh06d28152000-08-09 18:03:12 +00001674 """Geometry manager Grid.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001675
Fredrik Lundh06d28152000-08-09 18:03:12 +00001676 Base class to use the methods grid_* in every widget."""
1677 # Thanks to Masazumi Yoshikawa (yosikawa@isi.edu)
1678 def grid_configure(self, cnf={}, **kw):
1679 """Position a widget in the parent widget in a grid. Use as options:
1680 column=number - use cell identified with given column (starting with 0)
1681 columnspan=number - this widget will span several columns
1682 in=master - use master to contain this widget
1683 ipadx=amount - add internal padding in x direction
1684 ipady=amount - add internal padding in y direction
1685 padx=amount - add padding in x direction
1686 pady=amount - add padding in y direction
1687 row=number - use cell identified with given row (starting with 0)
1688 rowspan=number - this widget will span several rows
1689 sticky=NSEW - if cell is larger on which sides will this
1690 widget stick to the cell boundary
1691 """
1692 self.tk.call(
1693 ('grid', 'configure', self._w)
1694 + self._options(cnf, kw))
1695 grid = configure = config = grid_configure
1696 bbox = grid_bbox = Misc.grid_bbox
1697 columnconfigure = grid_columnconfigure = Misc.grid_columnconfigure
1698 def grid_forget(self):
1699 """Unmap this widget."""
1700 self.tk.call('grid', 'forget', self._w)
1701 forget = grid_forget
1702 def grid_remove(self):
1703 """Unmap this widget but remember the grid options."""
1704 self.tk.call('grid', 'remove', self._w)
1705 def grid_info(self):
1706 """Return information about the options
1707 for positioning this widget in a grid."""
1708 words = self.tk.splitlist(
1709 self.tk.call('grid', 'info', self._w))
1710 dict = {}
1711 for i in range(0, len(words), 2):
1712 key = words[i][1:]
1713 value = words[i+1]
1714 if value[:1] == '.':
1715 value = self._nametowidget(value)
1716 dict[key] = value
1717 return dict
1718 info = grid_info
Martin v. Löwisdc579092001-10-13 09:33:51 +00001719 location = grid_location = Misc.grid_location
Fredrik Lundh06d28152000-08-09 18:03:12 +00001720 propagate = grid_propagate = Misc.grid_propagate
1721 rowconfigure = grid_rowconfigure = Misc.grid_rowconfigure
1722 size = grid_size = Misc.grid_size
1723 slaves = grid_slaves = Misc.grid_slaves
Guido van Rossum37dcab11996-05-16 16:00:19 +00001724
Guido van Rossum368e06b1997-11-07 20:38:49 +00001725class BaseWidget(Misc):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001726 """Internal class."""
1727 def _setup(self, master, cnf):
1728 """Internal function. Sets up information about children."""
1729 if _support_default_root:
1730 global _default_root
1731 if not master:
1732 if not _default_root:
1733 _default_root = Tk()
1734 master = _default_root
1735 self.master = master
1736 self.tk = master.tk
1737 name = None
1738 if cnf.has_key('name'):
1739 name = cnf['name']
1740 del cnf['name']
1741 if not name:
1742 name = `id(self)`
1743 self._name = name
1744 if master._w=='.':
1745 self._w = '.' + name
1746 else:
1747 self._w = master._w + '.' + name
1748 self.children = {}
1749 if self.master.children.has_key(self._name):
1750 self.master.children[self._name].destroy()
1751 self.master.children[self._name] = self
1752 def __init__(self, master, widgetName, cnf={}, kw={}, extra=()):
1753 """Construct a widget with the parent widget MASTER, a name WIDGETNAME
1754 and appropriate options."""
1755 if kw:
1756 cnf = _cnfmerge((cnf, kw))
1757 self.widgetName = widgetName
1758 BaseWidget._setup(self, master, cnf)
1759 classes = []
1760 for k in cnf.keys():
1761 if type(k) is ClassType:
1762 classes.append((k, cnf[k]))
1763 del cnf[k]
1764 self.tk.call(
1765 (widgetName, self._w) + extra + self._options(cnf))
1766 for k, v in classes:
1767 k.configure(self, v)
1768 def destroy(self):
1769 """Destroy this and all descendants widgets."""
1770 for c in self.children.values(): c.destroy()
1771 if self.master.children.has_key(self._name):
1772 del self.master.children[self._name]
1773 self.tk.call('destroy', self._w)
1774 Misc.destroy(self)
1775 def _do(self, name, args=()):
1776 # XXX Obsolete -- better use self.tk.call directly!
1777 return self.tk.call((self._w, name) + args)
Guido van Rossum18468821994-06-20 07:49:28 +00001778
Guido van Rossum368e06b1997-11-07 20:38:49 +00001779class Widget(BaseWidget, Pack, Place, Grid):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001780 """Internal class.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001781
Fredrik Lundh06d28152000-08-09 18:03:12 +00001782 Base class for a widget which can be positioned with the geometry managers
1783 Pack, Place or Grid."""
1784 pass
Guido van Rossum368e06b1997-11-07 20:38:49 +00001785
1786class Toplevel(BaseWidget, Wm):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001787 """Toplevel widget, e.g. for dialogs."""
1788 def __init__(self, master=None, cnf={}, **kw):
1789 """Construct a toplevel widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001790
Fredrik Lundh06d28152000-08-09 18:03:12 +00001791 Valid resource names: background, bd, bg, borderwidth, class,
1792 colormap, container, cursor, height, highlightbackground,
1793 highlightcolor, highlightthickness, menu, relief, screen, takefocus,
1794 use, visual, width."""
1795 if kw:
1796 cnf = _cnfmerge((cnf, kw))
1797 extra = ()
1798 for wmkey in ['screen', 'class_', 'class', 'visual',
1799 'colormap']:
1800 if cnf.has_key(wmkey):
1801 val = cnf[wmkey]
1802 # TBD: a hack needed because some keys
1803 # are not valid as keyword arguments
1804 if wmkey[-1] == '_': opt = '-'+wmkey[:-1]
1805 else: opt = '-'+wmkey
1806 extra = extra + (opt, val)
1807 del cnf[wmkey]
1808 BaseWidget.__init__(self, master, 'toplevel', cnf, {}, extra)
1809 root = self._root()
1810 self.iconname(root.iconname())
1811 self.title(root.title())
1812 self.protocol("WM_DELETE_WINDOW", self.destroy)
Guido van Rossum18468821994-06-20 07:49:28 +00001813
1814class Button(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001815 """Button widget."""
1816 def __init__(self, master=None, cnf={}, **kw):
1817 """Construct a button widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001818
Fredrik Lundh06d28152000-08-09 18:03:12 +00001819 Valid resource names: activebackground, activeforeground, anchor,
1820 background, bd, bg, bitmap, borderwidth, command, cursor, default,
1821 disabledforeground, fg, font, foreground, height,
1822 highlightbackground, highlightcolor, highlightthickness, image,
1823 justify, padx, pady, relief, state, takefocus, text, textvariable,
1824 underline, width, wraplength."""
1825 Widget.__init__(self, master, 'button', cnf, kw)
1826 def tkButtonEnter(self, *dummy):
1827 self.tk.call('tkButtonEnter', self._w)
1828 def tkButtonLeave(self, *dummy):
1829 self.tk.call('tkButtonLeave', self._w)
1830 def tkButtonDown(self, *dummy):
1831 self.tk.call('tkButtonDown', self._w)
1832 def tkButtonUp(self, *dummy):
1833 self.tk.call('tkButtonUp', self._w)
1834 def tkButtonInvoke(self, *dummy):
1835 self.tk.call('tkButtonInvoke', self._w)
1836 def flash(self):
1837 self.tk.call(self._w, 'flash')
1838 def invoke(self):
1839 return self.tk.call(self._w, 'invoke')
Guido van Rossum18468821994-06-20 07:49:28 +00001840
1841# Indices:
Guido van Rossum35f67fb1995-08-04 03:50:29 +00001842# XXX I don't like these -- take them away
Guido van Rossum18468821994-06-20 07:49:28 +00001843def AtEnd():
Fredrik Lundh06d28152000-08-09 18:03:12 +00001844 return 'end'
Guido van Rossum1e9e4001994-06-20 09:09:51 +00001845def AtInsert(*args):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001846 s = 'insert'
1847 for a in args:
1848 if a: s = s + (' ' + a)
1849 return s
Guido van Rossum18468821994-06-20 07:49:28 +00001850def AtSelFirst():
Fredrik Lundh06d28152000-08-09 18:03:12 +00001851 return 'sel.first'
Guido van Rossum18468821994-06-20 07:49:28 +00001852def AtSelLast():
Fredrik Lundh06d28152000-08-09 18:03:12 +00001853 return 'sel.last'
Guido van Rossum18468821994-06-20 07:49:28 +00001854def At(x, y=None):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001855 if y is None:
1856 return '@' + `x`
1857 else:
1858 return '@' + `x` + ',' + `y`
Guido van Rossum18468821994-06-20 07:49:28 +00001859
1860class Canvas(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001861 """Canvas widget to display graphical elements like lines or text."""
1862 def __init__(self, master=None, cnf={}, **kw):
1863 """Construct a canvas widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001864
Fredrik Lundh06d28152000-08-09 18:03:12 +00001865 Valid resource names: background, bd, bg, borderwidth, closeenough,
1866 confine, cursor, height, highlightbackground, highlightcolor,
1867 highlightthickness, insertbackground, insertborderwidth,
1868 insertofftime, insertontime, insertwidth, offset, relief,
1869 scrollregion, selectbackground, selectborderwidth, selectforeground,
1870 state, takefocus, width, xscrollcommand, xscrollincrement,
1871 yscrollcommand, yscrollincrement."""
1872 Widget.__init__(self, master, 'canvas', cnf, kw)
1873 def addtag(self, *args):
1874 """Internal function."""
1875 self.tk.call((self._w, 'addtag') + args)
1876 def addtag_above(self, newtag, tagOrId):
1877 """Add tag NEWTAG to all items above TAGORID."""
1878 self.addtag(newtag, 'above', tagOrId)
1879 def addtag_all(self, newtag):
1880 """Add tag NEWTAG to all items."""
1881 self.addtag(newtag, 'all')
1882 def addtag_below(self, newtag, tagOrId):
1883 """Add tag NEWTAG to all items below TAGORID."""
1884 self.addtag(newtag, 'below', tagOrId)
1885 def addtag_closest(self, newtag, x, y, halo=None, start=None):
1886 """Add tag NEWTAG to item which is closest to pixel at X, Y.
1887 If several match take the top-most.
1888 All items closer than HALO are considered overlapping (all are
1889 closests). If START is specified the next below this tag is taken."""
1890 self.addtag(newtag, 'closest', x, y, halo, start)
1891 def addtag_enclosed(self, newtag, x1, y1, x2, y2):
1892 """Add tag NEWTAG to all items in the rectangle defined
1893 by X1,Y1,X2,Y2."""
1894 self.addtag(newtag, 'enclosed', x1, y1, x2, y2)
1895 def addtag_overlapping(self, newtag, x1, y1, x2, y2):
1896 """Add tag NEWTAG to all items which overlap the rectangle
1897 defined by X1,Y1,X2,Y2."""
1898 self.addtag(newtag, 'overlapping', x1, y1, x2, y2)
1899 def addtag_withtag(self, newtag, tagOrId):
1900 """Add tag NEWTAG to all items with TAGORID."""
1901 self.addtag(newtag, 'withtag', tagOrId)
1902 def bbox(self, *args):
1903 """Return a tuple of X1,Y1,X2,Y2 coordinates for a rectangle
1904 which encloses all items with tags specified as arguments."""
1905 return self._getints(
1906 self.tk.call((self._w, 'bbox') + args)) or None
1907 def tag_unbind(self, tagOrId, sequence, funcid=None):
1908 """Unbind for all items with TAGORID for event SEQUENCE the
1909 function identified with FUNCID."""
1910 self.tk.call(self._w, 'bind', tagOrId, sequence, '')
1911 if funcid:
1912 self.deletecommand(funcid)
1913 def tag_bind(self, tagOrId, sequence=None, func=None, add=None):
1914 """Bind to all items with TAGORID at event SEQUENCE a call to function FUNC.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001915
Fredrik Lundh06d28152000-08-09 18:03:12 +00001916 An additional boolean parameter ADD specifies whether FUNC will be
1917 called additionally to the other bound function or whether it will
1918 replace the previous function. See bind for the return value."""
1919 return self._bind((self._w, 'bind', tagOrId),
1920 sequence, func, add)
1921 def canvasx(self, screenx, gridspacing=None):
1922 """Return the canvas x coordinate of pixel position SCREENX rounded
1923 to nearest multiple of GRIDSPACING units."""
1924 return getdouble(self.tk.call(
1925 self._w, 'canvasx', screenx, gridspacing))
1926 def canvasy(self, screeny, gridspacing=None):
1927 """Return the canvas y coordinate of pixel position SCREENY rounded
1928 to nearest multiple of GRIDSPACING units."""
1929 return getdouble(self.tk.call(
1930 self._w, 'canvasy', screeny, gridspacing))
1931 def coords(self, *args):
1932 """Return a list of coordinates for the item given in ARGS."""
1933 # XXX Should use _flatten on args
1934 return map(getdouble,
Guido van Rossum0bd54331998-05-19 21:18:13 +00001935 self.tk.splitlist(
Fredrik Lundh06d28152000-08-09 18:03:12 +00001936 self.tk.call((self._w, 'coords') + args)))
1937 def _create(self, itemType, args, kw): # Args: (val, val, ..., cnf={})
1938 """Internal function."""
1939 args = _flatten(args)
1940 cnf = args[-1]
1941 if type(cnf) in (DictionaryType, TupleType):
1942 args = args[:-1]
1943 else:
1944 cnf = {}
1945 return getint(apply(
1946 self.tk.call,
1947 (self._w, 'create', itemType)
1948 + args + self._options(cnf, kw)))
1949 def create_arc(self, *args, **kw):
1950 """Create arc shaped region with coordinates x1,y1,x2,y2."""
1951 return self._create('arc', args, kw)
1952 def create_bitmap(self, *args, **kw):
1953 """Create bitmap with coordinates x1,y1."""
1954 return self._create('bitmap', args, kw)
1955 def create_image(self, *args, **kw):
1956 """Create image item with coordinates x1,y1."""
1957 return self._create('image', args, kw)
1958 def create_line(self, *args, **kw):
1959 """Create line with coordinates x1,y1,...,xn,yn."""
1960 return self._create('line', args, kw)
1961 def create_oval(self, *args, **kw):
1962 """Create oval with coordinates x1,y1,x2,y2."""
1963 return self._create('oval', args, kw)
1964 def create_polygon(self, *args, **kw):
1965 """Create polygon with coordinates x1,y1,...,xn,yn."""
1966 return self._create('polygon', args, kw)
1967 def create_rectangle(self, *args, **kw):
1968 """Create rectangle with coordinates x1,y1,x2,y2."""
1969 return self._create('rectangle', args, kw)
1970 def create_text(self, *args, **kw):
1971 """Create text with coordinates x1,y1."""
1972 return self._create('text', args, kw)
1973 def create_window(self, *args, **kw):
1974 """Create window with coordinates x1,y1,x2,y2."""
1975 return self._create('window', args, kw)
1976 def dchars(self, *args):
1977 """Delete characters of text items identified by tag or id in ARGS (possibly
1978 several times) from FIRST to LAST character (including)."""
1979 self.tk.call((self._w, 'dchars') + args)
1980 def delete(self, *args):
1981 """Delete items identified by all tag or ids contained in ARGS."""
1982 self.tk.call((self._w, 'delete') + args)
1983 def dtag(self, *args):
1984 """Delete tag or id given as last arguments in ARGS from items
1985 identified by first argument in ARGS."""
1986 self.tk.call((self._w, 'dtag') + args)
1987 def find(self, *args):
1988 """Internal function."""
1989 return self._getints(
1990 self.tk.call((self._w, 'find') + args)) or ()
1991 def find_above(self, tagOrId):
1992 """Return items above TAGORID."""
1993 return self.find('above', tagOrId)
1994 def find_all(self):
1995 """Return all items."""
1996 return self.find('all')
1997 def find_below(self, tagOrId):
1998 """Return all items below TAGORID."""
1999 return self.find('below', tagOrId)
2000 def find_closest(self, x, y, halo=None, start=None):
2001 """Return item which is closest to pixel at X, Y.
2002 If several match take the top-most.
2003 All items closer than HALO are considered overlapping (all are
2004 closests). If START is specified the next below this tag is taken."""
2005 return self.find('closest', x, y, halo, start)
2006 def find_enclosed(self, x1, y1, x2, y2):
2007 """Return all items in rectangle defined
2008 by X1,Y1,X2,Y2."""
2009 return self.find('enclosed', x1, y1, x2, y2)
2010 def find_overlapping(self, x1, y1, x2, y2):
2011 """Return all items which overlap the rectangle
2012 defined by X1,Y1,X2,Y2."""
2013 return self.find('overlapping', x1, y1, x2, y2)
2014 def find_withtag(self, tagOrId):
2015 """Return all items with TAGORID."""
2016 return self.find('withtag', tagOrId)
2017 def focus(self, *args):
2018 """Set focus to the first item specified in ARGS."""
2019 return self.tk.call((self._w, 'focus') + args)
2020 def gettags(self, *args):
2021 """Return tags associated with the first item specified in ARGS."""
2022 return self.tk.splitlist(
2023 self.tk.call((self._w, 'gettags') + args))
2024 def icursor(self, *args):
2025 """Set cursor at position POS in the item identified by TAGORID.
2026 In ARGS TAGORID must be first."""
2027 self.tk.call((self._w, 'icursor') + args)
2028 def index(self, *args):
2029 """Return position of cursor as integer in item specified in ARGS."""
2030 return getint(self.tk.call((self._w, 'index') + args))
2031 def insert(self, *args):
2032 """Insert TEXT in item TAGORID at position POS. ARGS must
2033 be TAGORID POS TEXT."""
2034 self.tk.call((self._w, 'insert') + args)
2035 def itemcget(self, tagOrId, option):
2036 """Return the resource value for an OPTION for item TAGORID."""
2037 return self.tk.call(
2038 (self._w, 'itemcget') + (tagOrId, '-'+option))
2039 def itemconfigure(self, tagOrId, cnf=None, **kw):
2040 """Configure resources of an item TAGORID.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002041
Fredrik Lundh06d28152000-08-09 18:03:12 +00002042 The values for resources are specified as keyword
2043 arguments. To get an overview about
2044 the allowed keyword arguments call the method without arguments.
2045 """
2046 if cnf is None and not kw:
2047 cnf = {}
2048 for x in self.tk.split(
2049 self.tk.call(self._w,
2050 'itemconfigure', tagOrId)):
2051 cnf[x[0][1:]] = (x[0][1:],) + x[1:]
2052 return cnf
2053 if type(cnf) == StringType and not kw:
2054 x = self.tk.split(self.tk.call(
2055 self._w, 'itemconfigure', tagOrId, '-'+cnf))
2056 return (x[0][1:],) + x[1:]
2057 self.tk.call((self._w, 'itemconfigure', tagOrId) +
2058 self._options(cnf, kw))
2059 itemconfig = itemconfigure
2060 # lower, tkraise/lift hide Misc.lower, Misc.tkraise/lift,
2061 # so the preferred name for them is tag_lower, tag_raise
2062 # (similar to tag_bind, and similar to the Text widget);
2063 # unfortunately can't delete the old ones yet (maybe in 1.6)
2064 def tag_lower(self, *args):
2065 """Lower an item TAGORID given in ARGS
2066 (optional below another item)."""
2067 self.tk.call((self._w, 'lower') + args)
2068 lower = tag_lower
2069 def move(self, *args):
2070 """Move an item TAGORID given in ARGS."""
2071 self.tk.call((self._w, 'move') + args)
2072 def postscript(self, cnf={}, **kw):
2073 """Print the contents of the canvas to a postscript
2074 file. Valid options: colormap, colormode, file, fontmap,
2075 height, pageanchor, pageheight, pagewidth, pagex, pagey,
2076 rotate, witdh, x, y."""
2077 return self.tk.call((self._w, 'postscript') +
2078 self._options(cnf, kw))
2079 def tag_raise(self, *args):
2080 """Raise an item TAGORID given in ARGS
2081 (optional above another item)."""
2082 self.tk.call((self._w, 'raise') + args)
2083 lift = tkraise = tag_raise
2084 def scale(self, *args):
2085 """Scale item TAGORID with XORIGIN, YORIGIN, XSCALE, YSCALE."""
2086 self.tk.call((self._w, 'scale') + args)
2087 def scan_mark(self, x, y):
2088 """Remember the current X, Y coordinates."""
2089 self.tk.call(self._w, 'scan', 'mark', x, y)
2090 def scan_dragto(self, x, y):
2091 """Adjust the view of the canvas to 10 times the
2092 difference between X and Y and the coordinates given in
2093 scan_mark."""
2094 self.tk.call(self._w, 'scan', 'dragto', x, y)
2095 def select_adjust(self, tagOrId, index):
2096 """Adjust the end of the selection near the cursor of an item TAGORID to index."""
2097 self.tk.call(self._w, 'select', 'adjust', tagOrId, index)
2098 def select_clear(self):
2099 """Clear the selection if it is in this widget."""
2100 self.tk.call(self._w, 'select', 'clear')
2101 def select_from(self, tagOrId, index):
2102 """Set the fixed end of a selection in item TAGORID to INDEX."""
2103 self.tk.call(self._w, 'select', 'from', tagOrId, index)
2104 def select_item(self):
2105 """Return the item which has the selection."""
2106 self.tk.call(self._w, 'select', 'item')
2107 def select_to(self, tagOrId, index):
2108 """Set the variable end of a selection in item TAGORID to INDEX."""
2109 self.tk.call(self._w, 'select', 'to', tagOrId, index)
2110 def type(self, tagOrId):
2111 """Return the type of the item TAGORID."""
2112 return self.tk.call(self._w, 'type', tagOrId) or None
2113 def xview(self, *args):
2114 """Query and change horizontal position of the view."""
2115 if not args:
2116 return self._getdoubles(self.tk.call(self._w, 'xview'))
2117 self.tk.call((self._w, 'xview') + args)
2118 def xview_moveto(self, fraction):
2119 """Adjusts the view in the window so that FRACTION of the
2120 total width of the canvas is off-screen to the left."""
2121 self.tk.call(self._w, 'xview', 'moveto', fraction)
2122 def xview_scroll(self, number, what):
2123 """Shift the x-view according to NUMBER which is measured in "units" or "pages" (WHAT)."""
2124 self.tk.call(self._w, 'xview', 'scroll', number, what)
2125 def yview(self, *args):
2126 """Query and change vertical position of the view."""
2127 if not args:
2128 return self._getdoubles(self.tk.call(self._w, 'yview'))
2129 self.tk.call((self._w, 'yview') + args)
2130 def yview_moveto(self, fraction):
2131 """Adjusts the view in the window so that FRACTION of the
2132 total height of the canvas is off-screen to the top."""
2133 self.tk.call(self._w, 'yview', 'moveto', fraction)
2134 def yview_scroll(self, number, what):
2135 """Shift the y-view according to NUMBER which is measured in "units" or "pages" (WHAT)."""
2136 self.tk.call(self._w, 'yview', 'scroll', number, what)
Guido van Rossum18468821994-06-20 07:49:28 +00002137
2138class Checkbutton(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002139 """Checkbutton widget which is either in on- or off-state."""
2140 def __init__(self, master=None, cnf={}, **kw):
2141 """Construct a checkbutton widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002142
Fredrik Lundh06d28152000-08-09 18:03:12 +00002143 Valid resource names: activebackground, activeforeground, anchor,
2144 background, bd, bg, bitmap, borderwidth, command, cursor,
2145 disabledforeground, fg, font, foreground, height,
2146 highlightbackground, highlightcolor, highlightthickness, image,
2147 indicatoron, justify, offvalue, onvalue, padx, pady, relief,
2148 selectcolor, selectimage, state, takefocus, text, textvariable,
2149 underline, variable, width, wraplength."""
2150 Widget.__init__(self, master, 'checkbutton', cnf, kw)
2151 def deselect(self):
2152 """Put the button in off-state."""
2153 self.tk.call(self._w, 'deselect')
2154 def flash(self):
2155 """Flash the button."""
2156 self.tk.call(self._w, 'flash')
2157 def invoke(self):
2158 """Toggle the button and invoke a command if given as resource."""
2159 return self.tk.call(self._w, 'invoke')
2160 def select(self):
2161 """Put the button in on-state."""
2162 self.tk.call(self._w, 'select')
2163 def toggle(self):
2164 """Toggle the button."""
2165 self.tk.call(self._w, 'toggle')
Guido van Rossum18468821994-06-20 07:49:28 +00002166
2167class Entry(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002168 """Entry widget which allows to display simple text."""
2169 def __init__(self, master=None, cnf={}, **kw):
2170 """Construct an entry widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002171
Fredrik Lundh06d28152000-08-09 18:03:12 +00002172 Valid resource names: background, bd, bg, borderwidth, cursor,
2173 exportselection, fg, font, foreground, highlightbackground,
2174 highlightcolor, highlightthickness, insertbackground,
2175 insertborderwidth, insertofftime, insertontime, insertwidth,
2176 invalidcommand, invcmd, justify, relief, selectbackground,
2177 selectborderwidth, selectforeground, show, state, takefocus,
2178 textvariable, validate, validatecommand, vcmd, width,
2179 xscrollcommand."""
2180 Widget.__init__(self, master, 'entry', cnf, kw)
2181 def delete(self, first, last=None):
2182 """Delete text from FIRST to LAST (not included)."""
2183 self.tk.call(self._w, 'delete', first, last)
2184 def get(self):
2185 """Return the text."""
2186 return self.tk.call(self._w, 'get')
2187 def icursor(self, index):
2188 """Insert cursor at INDEX."""
2189 self.tk.call(self._w, 'icursor', index)
2190 def index(self, index):
2191 """Return position of cursor."""
2192 return getint(self.tk.call(
2193 self._w, 'index', index))
2194 def insert(self, index, string):
2195 """Insert STRING at INDEX."""
2196 self.tk.call(self._w, 'insert', index, string)
2197 def scan_mark(self, x):
2198 """Remember the current X, Y coordinates."""
2199 self.tk.call(self._w, 'scan', 'mark', x)
2200 def scan_dragto(self, x):
2201 """Adjust the view of the canvas to 10 times the
2202 difference between X and Y and the coordinates given in
2203 scan_mark."""
2204 self.tk.call(self._w, 'scan', 'dragto', x)
2205 def selection_adjust(self, index):
2206 """Adjust the end of the selection near the cursor to INDEX."""
2207 self.tk.call(self._w, 'selection', 'adjust', index)
2208 select_adjust = selection_adjust
2209 def selection_clear(self):
2210 """Clear the selection if it is in this widget."""
2211 self.tk.call(self._w, 'selection', 'clear')
2212 select_clear = selection_clear
2213 def selection_from(self, index):
2214 """Set the fixed end of a selection to INDEX."""
2215 self.tk.call(self._w, 'selection', 'from', index)
2216 select_from = selection_from
2217 def selection_present(self):
2218 """Return whether the widget has the selection."""
2219 return self.tk.getboolean(
2220 self.tk.call(self._w, 'selection', 'present'))
2221 select_present = selection_present
2222 def selection_range(self, start, end):
2223 """Set the selection from START to END (not included)."""
2224 self.tk.call(self._w, 'selection', 'range', start, end)
2225 select_range = selection_range
2226 def selection_to(self, index):
2227 """Set the variable end of a selection to INDEX."""
2228 self.tk.call(self._w, 'selection', 'to', index)
2229 select_to = selection_to
2230 def xview(self, index):
2231 """Query and change horizontal position of the view."""
2232 self.tk.call(self._w, 'xview', index)
2233 def xview_moveto(self, fraction):
2234 """Adjust the view in the window so that FRACTION of the
2235 total width of the entry is off-screen to the left."""
2236 self.tk.call(self._w, 'xview', 'moveto', fraction)
2237 def xview_scroll(self, number, what):
2238 """Shift the x-view according to NUMBER which is measured in "units" or "pages" (WHAT)."""
2239 self.tk.call(self._w, 'xview', 'scroll', number, what)
Guido van Rossum18468821994-06-20 07:49:28 +00002240
2241class Frame(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002242 """Frame widget which may contain other widgets and can have a 3D border."""
2243 def __init__(self, master=None, cnf={}, **kw):
2244 """Construct a frame widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002245
Fredrik Lundh06d28152000-08-09 18:03:12 +00002246 Valid resource names: background, bd, bg, borderwidth, class,
2247 colormap, container, cursor, height, highlightbackground,
2248 highlightcolor, highlightthickness, relief, takefocus, visual, width."""
2249 cnf = _cnfmerge((cnf, kw))
2250 extra = ()
2251 if cnf.has_key('class_'):
2252 extra = ('-class', cnf['class_'])
2253 del cnf['class_']
2254 elif cnf.has_key('class'):
2255 extra = ('-class', cnf['class'])
2256 del cnf['class']
2257 Widget.__init__(self, master, 'frame', cnf, {}, extra)
Guido van Rossum18468821994-06-20 07:49:28 +00002258
2259class Label(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002260 """Label widget which can display text and bitmaps."""
2261 def __init__(self, master=None, cnf={}, **kw):
2262 """Construct a label widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002263
Fredrik Lundh06d28152000-08-09 18:03:12 +00002264 Valid resource names: anchor, background, bd, bg, bitmap,
2265 borderwidth, cursor, fg, font, foreground, height,
2266 highlightbackground, highlightcolor, highlightthickness, image,
2267 justify, padx, pady, relief, takefocus, text, textvariable,
2268 underline, width, wraplength."""
2269 Widget.__init__(self, master, 'label', cnf, kw)
Guido van Rossum761c5ab1995-07-14 15:29:10 +00002270
Guido van Rossum18468821994-06-20 07:49:28 +00002271class Listbox(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002272 """Listbox widget which can display a list of strings."""
2273 def __init__(self, master=None, cnf={}, **kw):
2274 """Construct a listbox widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002275
Fredrik Lundh06d28152000-08-09 18:03:12 +00002276 Valid resource names: background, bd, bg, borderwidth, cursor,
2277 exportselection, fg, font, foreground, height, highlightbackground,
2278 highlightcolor, highlightthickness, relief, selectbackground,
2279 selectborderwidth, selectforeground, selectmode, setgrid, takefocus,
2280 width, xscrollcommand, yscrollcommand, listvariable."""
2281 Widget.__init__(self, master, 'listbox', cnf, kw)
2282 def activate(self, index):
2283 """Activate item identified by INDEX."""
2284 self.tk.call(self._w, 'activate', index)
2285 def bbox(self, *args):
2286 """Return a tuple of X1,Y1,X2,Y2 coordinates for a rectangle
2287 which encloses the item identified by index in ARGS."""
2288 return self._getints(
2289 self.tk.call((self._w, 'bbox') + args)) or None
2290 def curselection(self):
2291 """Return list of indices of currently selected item."""
2292 # XXX Ought to apply self._getints()...
2293 return self.tk.splitlist(self.tk.call(
2294 self._w, 'curselection'))
2295 def delete(self, first, last=None):
2296 """Delete items from FIRST to LAST (not included)."""
2297 self.tk.call(self._w, 'delete', first, last)
2298 def get(self, first, last=None):
2299 """Get list of items from FIRST to LAST (not included)."""
2300 if last:
2301 return self.tk.splitlist(self.tk.call(
2302 self._w, 'get', first, last))
2303 else:
2304 return self.tk.call(self._w, 'get', first)
2305 def index(self, index):
2306 """Return index of item identified with INDEX."""
2307 i = self.tk.call(self._w, 'index', index)
2308 if i == 'none': return None
2309 return getint(i)
2310 def insert(self, index, *elements):
2311 """Insert ELEMENTS at INDEX."""
2312 self.tk.call((self._w, 'insert', index) + elements)
2313 def nearest(self, y):
2314 """Get index of item which is nearest to y coordinate Y."""
2315 return getint(self.tk.call(
2316 self._w, 'nearest', y))
2317 def scan_mark(self, x, y):
2318 """Remember the current X, Y coordinates."""
2319 self.tk.call(self._w, 'scan', 'mark', x, y)
2320 def scan_dragto(self, x, y):
2321 """Adjust the view of the listbox to 10 times the
2322 difference between X and Y and the coordinates given in
2323 scan_mark."""
2324 self.tk.call(self._w, 'scan', 'dragto', x, y)
2325 def see(self, index):
2326 """Scroll such that INDEX is visible."""
2327 self.tk.call(self._w, 'see', index)
2328 def selection_anchor(self, index):
2329 """Set the fixed end oft the selection to INDEX."""
2330 self.tk.call(self._w, 'selection', 'anchor', index)
2331 select_anchor = selection_anchor
2332 def selection_clear(self, first, last=None):
2333 """Clear the selection from FIRST to LAST (not included)."""
2334 self.tk.call(self._w,
2335 'selection', 'clear', first, last)
2336 select_clear = selection_clear
2337 def selection_includes(self, index):
2338 """Return 1 if INDEX is part of the selection."""
2339 return self.tk.getboolean(self.tk.call(
2340 self._w, 'selection', 'includes', index))
2341 select_includes = selection_includes
2342 def selection_set(self, first, last=None):
2343 """Set the selection from FIRST to LAST (not included) without
2344 changing the currently selected elements."""
2345 self.tk.call(self._w, 'selection', 'set', first, last)
2346 select_set = selection_set
2347 def size(self):
2348 """Return the number of elements in the listbox."""
2349 return getint(self.tk.call(self._w, 'size'))
2350 def xview(self, *what):
2351 """Query and change horizontal position of the view."""
2352 if not what:
2353 return self._getdoubles(self.tk.call(self._w, 'xview'))
2354 self.tk.call((self._w, 'xview') + what)
2355 def xview_moveto(self, fraction):
2356 """Adjust the view in the window so that FRACTION of the
2357 total width of the entry is off-screen to the left."""
2358 self.tk.call(self._w, 'xview', 'moveto', fraction)
2359 def xview_scroll(self, number, what):
2360 """Shift the x-view according to NUMBER which is measured in "units" or "pages" (WHAT)."""
2361 self.tk.call(self._w, 'xview', 'scroll', number, what)
2362 def yview(self, *what):
2363 """Query and change vertical position of the view."""
2364 if not what:
2365 return self._getdoubles(self.tk.call(self._w, 'yview'))
2366 self.tk.call((self._w, 'yview') + what)
2367 def yview_moveto(self, fraction):
2368 """Adjust the view in the window so that FRACTION of the
2369 total width of the entry is off-screen to the top."""
2370 self.tk.call(self._w, 'yview', 'moveto', fraction)
2371 def yview_scroll(self, number, what):
2372 """Shift the y-view according to NUMBER which is measured in "units" or "pages" (WHAT)."""
2373 self.tk.call(self._w, 'yview', 'scroll', number, what)
Guido van Rossum09f1ad82001-09-05 19:29:56 +00002374 def itemcget(self, index, option):
2375 """Return the resource value for an ITEM and an OPTION."""
2376 return self.tk.call(
2377 (self._w, 'itemcget') + (index, '-'+option))
Guido van Rossuma0adb922001-09-01 18:29:55 +00002378 def itemconfigure(self, index, cnf=None, **kw):
Guido van Rossum09f1ad82001-09-05 19:29:56 +00002379 """Configure resources of an ITEM.
Guido van Rossuma0adb922001-09-01 18:29:55 +00002380
2381 The values for resources are specified as keyword arguments.
2382 To get an overview about the allowed keyword arguments
2383 call the method without arguments.
2384 Valid resource names: background, bg, foreground, fg,
2385 selectbackground, selectforeground."""
2386 if cnf is None and not kw:
2387 cnf = {}
2388 for x in self.tk.split(
2389 self.tk.call(self._w, 'itemconfigure', index)):
2390 cnf[x[0][1:]] = (x[0][1:],) + x[1:]
2391 return cnf
2392 if type(cnf) == StringType and not kw:
2393 x = self.tk.split(self.tk.call(
2394 self._w, 'itemconfigure', index, '-'+cnf))
2395 return (x[0][1:],) + x[1:]
2396 self.tk.call((self._w, 'itemconfigure', index) +
2397 self._options(cnf, kw))
2398 itemconfig = itemconfigure
Guido van Rossum18468821994-06-20 07:49:28 +00002399
2400class Menu(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002401 """Menu widget which allows to display menu bars, pull-down menus and pop-up menus."""
2402 def __init__(self, master=None, cnf={}, **kw):
2403 """Construct menu widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002404
Fredrik Lundh06d28152000-08-09 18:03:12 +00002405 Valid resource names: activebackground, activeborderwidth,
2406 activeforeground, background, bd, bg, borderwidth, cursor,
2407 disabledforeground, fg, font, foreground, postcommand, relief,
2408 selectcolor, takefocus, tearoff, tearoffcommand, title, type."""
2409 Widget.__init__(self, master, 'menu', cnf, kw)
2410 def tk_bindForTraversal(self):
2411 pass # obsolete since Tk 4.0
2412 def tk_mbPost(self):
2413 self.tk.call('tk_mbPost', self._w)
2414 def tk_mbUnpost(self):
2415 self.tk.call('tk_mbUnpost')
2416 def tk_traverseToMenu(self, char):
2417 self.tk.call('tk_traverseToMenu', self._w, char)
2418 def tk_traverseWithinMenu(self, char):
2419 self.tk.call('tk_traverseWithinMenu', self._w, char)
2420 def tk_getMenuButtons(self):
2421 return self.tk.call('tk_getMenuButtons', self._w)
2422 def tk_nextMenu(self, count):
2423 self.tk.call('tk_nextMenu', count)
2424 def tk_nextMenuEntry(self, count):
2425 self.tk.call('tk_nextMenuEntry', count)
2426 def tk_invokeMenu(self):
2427 self.tk.call('tk_invokeMenu', self._w)
2428 def tk_firstMenu(self):
2429 self.tk.call('tk_firstMenu', self._w)
2430 def tk_mbButtonDown(self):
2431 self.tk.call('tk_mbButtonDown', self._w)
2432 def tk_popup(self, x, y, entry=""):
2433 """Post the menu at position X,Y with entry ENTRY."""
2434 self.tk.call('tk_popup', self._w, x, y, entry)
2435 def activate(self, index):
2436 """Activate entry at INDEX."""
2437 self.tk.call(self._w, 'activate', index)
2438 def add(self, itemType, cnf={}, **kw):
2439 """Internal function."""
2440 self.tk.call((self._w, 'add', itemType) +
2441 self._options(cnf, kw))
2442 def add_cascade(self, cnf={}, **kw):
2443 """Add hierarchical menu item."""
2444 self.add('cascade', cnf or kw)
2445 def add_checkbutton(self, cnf={}, **kw):
2446 """Add checkbutton menu item."""
2447 self.add('checkbutton', cnf or kw)
2448 def add_command(self, cnf={}, **kw):
2449 """Add command menu item."""
2450 self.add('command', cnf or kw)
2451 def add_radiobutton(self, cnf={}, **kw):
2452 """Addd radio menu item."""
2453 self.add('radiobutton', cnf or kw)
2454 def add_separator(self, cnf={}, **kw):
2455 """Add separator."""
2456 self.add('separator', cnf or kw)
2457 def insert(self, index, itemType, cnf={}, **kw):
2458 """Internal function."""
2459 self.tk.call((self._w, 'insert', index, itemType) +
2460 self._options(cnf, kw))
2461 def insert_cascade(self, index, cnf={}, **kw):
2462 """Add hierarchical menu item at INDEX."""
2463 self.insert(index, 'cascade', cnf or kw)
2464 def insert_checkbutton(self, index, cnf={}, **kw):
2465 """Add checkbutton menu item at INDEX."""
2466 self.insert(index, 'checkbutton', cnf or kw)
2467 def insert_command(self, index, cnf={}, **kw):
2468 """Add command menu item at INDEX."""
2469 self.insert(index, 'command', cnf or kw)
2470 def insert_radiobutton(self, index, cnf={}, **kw):
2471 """Addd radio menu item at INDEX."""
2472 self.insert(index, 'radiobutton', cnf or kw)
2473 def insert_separator(self, index, cnf={}, **kw):
2474 """Add separator at INDEX."""
2475 self.insert(index, 'separator', cnf or kw)
2476 def delete(self, index1, index2=None):
2477 """Delete menu items between INDEX1 and INDEX2 (not included)."""
2478 self.tk.call(self._w, 'delete', index1, index2)
2479 def entrycget(self, index, option):
2480 """Return the resource value of an menu item for OPTION at INDEX."""
2481 return self.tk.call(self._w, 'entrycget', index, '-' + option)
2482 def entryconfigure(self, index, cnf=None, **kw):
2483 """Configure a menu item at INDEX."""
2484 if cnf is None and not kw:
2485 cnf = {}
2486 for x in self.tk.split(self.tk.call(
2487 (self._w, 'entryconfigure', index))):
2488 cnf[x[0][1:]] = (x[0][1:],) + x[1:]
2489 return cnf
2490 if type(cnf) == StringType and not kw:
2491 x = self.tk.split(self.tk.call(
2492 (self._w, 'entryconfigure', index, '-'+cnf)))
2493 return (x[0][1:],) + x[1:]
2494 self.tk.call((self._w, 'entryconfigure', index)
2495 + self._options(cnf, kw))
2496 entryconfig = entryconfigure
2497 def index(self, index):
2498 """Return the index of a menu item identified by INDEX."""
2499 i = self.tk.call(self._w, 'index', index)
2500 if i == 'none': return None
2501 return getint(i)
2502 def invoke(self, index):
2503 """Invoke a menu item identified by INDEX and execute
2504 the associated command."""
2505 return self.tk.call(self._w, 'invoke', index)
2506 def post(self, x, y):
2507 """Display a menu at position X,Y."""
2508 self.tk.call(self._w, 'post', x, y)
2509 def type(self, index):
2510 """Return the type of the menu item at INDEX."""
2511 return self.tk.call(self._w, 'type', index)
2512 def unpost(self):
2513 """Unmap a menu."""
2514 self.tk.call(self._w, 'unpost')
2515 def yposition(self, index):
2516 """Return the y-position of the topmost pixel of the menu item at INDEX."""
2517 return getint(self.tk.call(
2518 self._w, 'yposition', index))
Guido van Rossum18468821994-06-20 07:49:28 +00002519
2520class Menubutton(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002521 """Menubutton widget, obsolete since Tk8.0."""
2522 def __init__(self, master=None, cnf={}, **kw):
2523 Widget.__init__(self, master, 'menubutton', cnf, kw)
Guido van Rossum18468821994-06-20 07:49:28 +00002524
2525class Message(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002526 """Message widget to display multiline text. Obsolete since Label does it too."""
2527 def __init__(self, master=None, cnf={}, **kw):
2528 Widget.__init__(self, master, 'message', cnf, kw)
Guido van Rossum18468821994-06-20 07:49:28 +00002529
2530class Radiobutton(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002531 """Radiobutton widget which shows only one of several buttons in on-state."""
2532 def __init__(self, master=None, cnf={}, **kw):
2533 """Construct a radiobutton widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002534
Fredrik Lundh06d28152000-08-09 18:03:12 +00002535 Valid resource names: activebackground, activeforeground, anchor,
2536 background, bd, bg, bitmap, borderwidth, command, cursor,
2537 disabledforeground, fg, font, foreground, height,
2538 highlightbackground, highlightcolor, highlightthickness, image,
2539 indicatoron, justify, padx, pady, relief, selectcolor, selectimage,
2540 state, takefocus, text, textvariable, underline, value, variable,
2541 width, wraplength."""
2542 Widget.__init__(self, master, 'radiobutton', cnf, kw)
2543 def deselect(self):
2544 """Put the button in off-state."""
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002545
Fredrik Lundh06d28152000-08-09 18:03:12 +00002546 self.tk.call(self._w, 'deselect')
2547 def flash(self):
2548 """Flash the button."""
2549 self.tk.call(self._w, 'flash')
2550 def invoke(self):
2551 """Toggle the button and invoke a command if given as resource."""
2552 return self.tk.call(self._w, 'invoke')
2553 def select(self):
2554 """Put the button in on-state."""
2555 self.tk.call(self._w, 'select')
Guido van Rossum18468821994-06-20 07:49:28 +00002556
2557class Scale(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002558 """Scale widget which can display a numerical scale."""
2559 def __init__(self, master=None, cnf={}, **kw):
2560 """Construct a scale widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002561
Fredrik Lundh06d28152000-08-09 18:03:12 +00002562 Valid resource names: activebackground, background, bigincrement, bd,
2563 bg, borderwidth, command, cursor, digits, fg, font, foreground, from,
2564 highlightbackground, highlightcolor, highlightthickness, label,
2565 length, orient, relief, repeatdelay, repeatinterval, resolution,
2566 showvalue, sliderlength, sliderrelief, state, takefocus,
2567 tickinterval, to, troughcolor, variable, width."""
2568 Widget.__init__(self, master, 'scale', cnf, kw)
2569 def get(self):
2570 """Get the current value as integer or float."""
2571 value = self.tk.call(self._w, 'get')
2572 try:
2573 return getint(value)
2574 except ValueError:
2575 return getdouble(value)
2576 def set(self, value):
2577 """Set the value to VALUE."""
2578 self.tk.call(self._w, 'set', value)
2579 def coords(self, value=None):
2580 """Return a tuple (X,Y) of the point along the centerline of the
2581 trough that corresponds to VALUE or the current value if None is
2582 given."""
2583
2584 return self._getints(self.tk.call(self._w, 'coords', value))
2585 def identify(self, x, y):
2586 """Return where the point X,Y lies. Valid return values are "slider",
2587 "though1" and "though2"."""
2588 return self.tk.call(self._w, 'identify', x, y)
Guido van Rossum18468821994-06-20 07:49:28 +00002589
2590class Scrollbar(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002591 """Scrollbar widget which displays a slider at a certain position."""
2592 def __init__(self, master=None, cnf={}, **kw):
2593 """Construct a scrollbar widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002594
Fredrik Lundh06d28152000-08-09 18:03:12 +00002595 Valid resource names: activebackground, activerelief,
2596 background, bd, bg, borderwidth, command, cursor,
2597 elementborderwidth, highlightbackground,
2598 highlightcolor, highlightthickness, jump, orient,
2599 relief, repeatdelay, repeatinterval, takefocus,
2600 troughcolor, width."""
2601 Widget.__init__(self, master, 'scrollbar', cnf, kw)
2602 def activate(self, index):
2603 """Display the element at INDEX with activebackground and activerelief.
2604 INDEX can be "arrow1","slider" or "arrow2"."""
2605 self.tk.call(self._w, 'activate', index)
2606 def delta(self, deltax, deltay):
2607 """Return the fractional change of the scrollbar setting if it
2608 would be moved by DELTAX or DELTAY pixels."""
2609 return getdouble(
2610 self.tk.call(self._w, 'delta', deltax, deltay))
2611 def fraction(self, x, y):
2612 """Return the fractional value which corresponds to a slider
2613 position of X,Y."""
2614 return getdouble(self.tk.call(self._w, 'fraction', x, y))
2615 def identify(self, x, y):
2616 """Return the element under position X,Y as one of
2617 "arrow1","slider","arrow2" or ""."""
2618 return self.tk.call(self._w, 'identify', x, y)
2619 def get(self):
2620 """Return the current fractional values (upper and lower end)
2621 of the slider position."""
2622 return self._getdoubles(self.tk.call(self._w, 'get'))
2623 def set(self, *args):
2624 """Set the fractional values of the slider position (upper and
2625 lower ends as value between 0 and 1)."""
2626 self.tk.call((self._w, 'set') + args)
Guido van Rossum18468821994-06-20 07:49:28 +00002627
2628class Text(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002629 """Text widget which can display text in various forms."""
Fredrik Lundh06d28152000-08-09 18:03:12 +00002630 def __init__(self, master=None, cnf={}, **kw):
2631 """Construct a text widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002632
Fredrik Lundh06d28152000-08-09 18:03:12 +00002633 Valid resource names: background, bd, bg, borderwidth, cursor,
2634 exportselection, fg, font, foreground, height,
2635 highlightbackground, highlightcolor, highlightthickness,
2636 insertbackground, insertborderwidth, insertofftime,
2637 insertontime, insertwidth, padx, pady, relief,
2638 selectbackground, selectborderwidth, selectforeground,
2639 setgrid, spacing1, spacing2, spacing3, state, tabs, takefocus,
2640 width, wrap, xscrollcommand, yscrollcommand."""
2641 Widget.__init__(self, master, 'text', cnf, kw)
2642 def bbox(self, *args):
2643 """Return a tuple of (x,y,width,height) which gives the bounding
2644 box of the visible part of the character at the index in ARGS."""
2645 return self._getints(
2646 self.tk.call((self._w, 'bbox') + args)) or None
2647 def tk_textSelectTo(self, index):
2648 self.tk.call('tk_textSelectTo', self._w, index)
2649 def tk_textBackspace(self):
2650 self.tk.call('tk_textBackspace', self._w)
2651 def tk_textIndexCloser(self, a, b, c):
2652 self.tk.call('tk_textIndexCloser', self._w, a, b, c)
2653 def tk_textResetAnchor(self, index):
2654 self.tk.call('tk_textResetAnchor', self._w, index)
2655 def compare(self, index1, op, index2):
2656 """Return whether between index INDEX1 and index INDEX2 the
2657 relation OP is satisfied. OP is one of <, <=, ==, >=, >, or !=."""
2658 return self.tk.getboolean(self.tk.call(
2659 self._w, 'compare', index1, op, index2))
2660 def debug(self, boolean=None):
2661 """Turn on the internal consistency checks of the B-Tree inside the text
2662 widget according to BOOLEAN."""
2663 return self.tk.getboolean(self.tk.call(
2664 self._w, 'debug', boolean))
2665 def delete(self, index1, index2=None):
2666 """Delete the characters between INDEX1 and INDEX2 (not included)."""
2667 self.tk.call(self._w, 'delete', index1, index2)
2668 def dlineinfo(self, index):
2669 """Return tuple (x,y,width,height,baseline) giving the bounding box
2670 and baseline position of the visible part of the line containing
2671 the character at INDEX."""
2672 return self._getints(self.tk.call(self._w, 'dlineinfo', index))
Guido van Rossum256705b2002-04-23 13:29:43 +00002673 def dump(self, index1, index2=None, command=None, **kw):
2674 """Return the contents of the widget between index1 and index2.
2675
2676 The type of contents returned in filtered based on the keyword
2677 parameters; if 'all', 'image', 'mark', 'tag', 'text', or 'window' are
2678 given and true, then the corresponding items are returned. The result
2679 is a list of triples of the form (key, value, index). If none of the
2680 keywords are true then 'all' is used by default.
2681
2682 If the 'command' argument is given, it is called once for each element
2683 of the list of triples, with the values of each triple serving as the
2684 arguments to the function. In this case the list is not returned."""
2685 args = []
2686 func_name = None
2687 result = None
2688 if not command:
2689 # Never call the dump command without the -command flag, since the
2690 # output could involve Tcl quoting and would be a pain to parse
2691 # right. Instead just set the command to build a list of triples
2692 # as if we had done the parsing.
2693 result = []
2694 def append_triple(key, value, index, result=result):
2695 result.append((key, value, index))
2696 command = append_triple
2697 try:
2698 if not isinstance(command, str):
2699 func_name = command = self._register(command)
2700 args += ["-command", command]
2701 for key in kw:
2702 if kw[key]: args.append("-" + key)
2703 args.append(index1)
2704 if index2:
2705 args.append(index2)
2706 self.tk.call(self._w, "dump", *args)
2707 return result
2708 finally:
2709 if func_name:
2710 self.deletecommand(func_name)
Fredrik Lundh06d28152000-08-09 18:03:12 +00002711 def get(self, index1, index2=None):
2712 """Return the text from INDEX1 to INDEX2 (not included)."""
2713 return self.tk.call(self._w, 'get', index1, index2)
2714 # (Image commands are new in 8.0)
2715 def image_cget(self, index, option):
2716 """Return the value of OPTION of an embedded image at INDEX."""
2717 if option[:1] != "-":
2718 option = "-" + option
2719 if option[-1:] == "_":
2720 option = option[:-1]
2721 return self.tk.call(self._w, "image", "cget", index, option)
2722 def image_configure(self, index, cnf={}, **kw):
2723 """Configure an embedded image at INDEX."""
2724 if not cnf and not kw:
2725 cnf = {}
2726 for x in self.tk.split(
2727 self.tk.call(
2728 self._w, "image", "configure", index)):
2729 cnf[x[0][1:]] = (x[0][1:],) + x[1:]
2730 return cnf
2731 apply(self.tk.call,
2732 (self._w, "image", "configure", index)
2733 + self._options(cnf, kw))
2734 def image_create(self, index, cnf={}, **kw):
2735 """Create an embedded image at INDEX."""
2736 return apply(self.tk.call,
2737 (self._w, "image", "create", index)
2738 + self._options(cnf, kw))
2739 def image_names(self):
2740 """Return all names of embedded images in this widget."""
2741 return self.tk.call(self._w, "image", "names")
2742 def index(self, index):
2743 """Return the index in the form line.char for INDEX."""
2744 return self.tk.call(self._w, 'index', index)
2745 def insert(self, index, chars, *args):
2746 """Insert CHARS before the characters at INDEX. An additional
2747 tag can be given in ARGS. Additional CHARS and tags can follow in ARGS."""
2748 self.tk.call((self._w, 'insert', index, chars) + args)
2749 def mark_gravity(self, markName, direction=None):
2750 """Change the gravity of a mark MARKNAME to DIRECTION (LEFT or RIGHT).
2751 Return the current value if None is given for DIRECTION."""
2752 return self.tk.call(
2753 (self._w, 'mark', 'gravity', markName, direction))
2754 def mark_names(self):
2755 """Return all mark names."""
2756 return self.tk.splitlist(self.tk.call(
2757 self._w, 'mark', 'names'))
2758 def mark_set(self, markName, index):
2759 """Set mark MARKNAME before the character at INDEX."""
2760 self.tk.call(self._w, 'mark', 'set', markName, index)
2761 def mark_unset(self, *markNames):
2762 """Delete all marks in MARKNAMES."""
2763 self.tk.call((self._w, 'mark', 'unset') + markNames)
2764 def mark_next(self, index):
2765 """Return the name of the next mark after INDEX."""
2766 return self.tk.call(self._w, 'mark', 'next', index) or None
2767 def mark_previous(self, index):
2768 """Return the name of the previous mark before INDEX."""
2769 return self.tk.call(self._w, 'mark', 'previous', index) or None
2770 def scan_mark(self, x, y):
2771 """Remember the current X, Y coordinates."""
2772 self.tk.call(self._w, 'scan', 'mark', x, y)
2773 def scan_dragto(self, x, y):
2774 """Adjust the view of the text to 10 times the
2775 difference between X and Y and the coordinates given in
2776 scan_mark."""
2777 self.tk.call(self._w, 'scan', 'dragto', x, y)
2778 def search(self, pattern, index, stopindex=None,
2779 forwards=None, backwards=None, exact=None,
2780 regexp=None, nocase=None, count=None):
2781 """Search PATTERN beginning from INDEX until STOPINDEX.
2782 Return the index of the first character of a match or an empty string."""
2783 args = [self._w, 'search']
2784 if forwards: args.append('-forwards')
2785 if backwards: args.append('-backwards')
2786 if exact: args.append('-exact')
2787 if regexp: args.append('-regexp')
2788 if nocase: args.append('-nocase')
2789 if count: args.append('-count'); args.append(count)
2790 if pattern[0] == '-': args.append('--')
2791 args.append(pattern)
2792 args.append(index)
2793 if stopindex: args.append(stopindex)
2794 return self.tk.call(tuple(args))
2795 def see(self, index):
2796 """Scroll such that the character at INDEX is visible."""
2797 self.tk.call(self._w, 'see', index)
2798 def tag_add(self, tagName, index1, *args):
2799 """Add tag TAGNAME to all characters between INDEX1 and index2 in ARGS.
2800 Additional pairs of indices may follow in ARGS."""
2801 self.tk.call(
2802 (self._w, 'tag', 'add', tagName, index1) + args)
2803 def tag_unbind(self, tagName, sequence, funcid=None):
2804 """Unbind for all characters with TAGNAME for event SEQUENCE the
2805 function identified with FUNCID."""
2806 self.tk.call(self._w, 'tag', 'bind', tagName, sequence, '')
2807 if funcid:
2808 self.deletecommand(funcid)
2809 def tag_bind(self, tagName, sequence, func, add=None):
2810 """Bind to all characters with TAGNAME at event SEQUENCE a call to function FUNC.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002811
Fredrik Lundh06d28152000-08-09 18:03:12 +00002812 An additional boolean parameter ADD specifies whether FUNC will be
2813 called additionally to the other bound function or whether it will
2814 replace the previous function. See bind for the return value."""
2815 return self._bind((self._w, 'tag', 'bind', tagName),
2816 sequence, func, add)
2817 def tag_cget(self, tagName, option):
2818 """Return the value of OPTION for tag TAGNAME."""
2819 if option[:1] != '-':
2820 option = '-' + option
2821 if option[-1:] == '_':
2822 option = option[:-1]
2823 return self.tk.call(self._w, 'tag', 'cget', tagName, option)
2824 def tag_configure(self, tagName, cnf={}, **kw):
2825 """Configure a tag TAGNAME."""
2826 if type(cnf) == StringType:
2827 x = self.tk.split(self.tk.call(
2828 self._w, 'tag', 'configure', tagName, '-'+cnf))
2829 return (x[0][1:],) + x[1:]
2830 self.tk.call(
2831 (self._w, 'tag', 'configure', tagName)
2832 + self._options(cnf, kw))
2833 tag_config = tag_configure
2834 def tag_delete(self, *tagNames):
2835 """Delete all tags in TAGNAMES."""
2836 self.tk.call((self._w, 'tag', 'delete') + tagNames)
2837 def tag_lower(self, tagName, belowThis=None):
2838 """Change the priority of tag TAGNAME such that it is lower
2839 than the priority of BELOWTHIS."""
2840 self.tk.call(self._w, 'tag', 'lower', tagName, belowThis)
2841 def tag_names(self, index=None):
2842 """Return a list of all tag names."""
2843 return self.tk.splitlist(
2844 self.tk.call(self._w, 'tag', 'names', index))
2845 def tag_nextrange(self, tagName, index1, index2=None):
2846 """Return a list of start and end index for the first sequence of
2847 characters between INDEX1 and INDEX2 which all have tag TAGNAME.
2848 The text is searched forward from INDEX1."""
2849 return self.tk.splitlist(self.tk.call(
2850 self._w, 'tag', 'nextrange', tagName, index1, index2))
2851 def tag_prevrange(self, tagName, index1, index2=None):
2852 """Return a list of start and end index for the first sequence of
2853 characters between INDEX1 and INDEX2 which all have tag TAGNAME.
2854 The text is searched backwards from INDEX1."""
2855 return self.tk.splitlist(self.tk.call(
2856 self._w, 'tag', 'prevrange', tagName, index1, index2))
2857 def tag_raise(self, tagName, aboveThis=None):
2858 """Change the priority of tag TAGNAME such that it is higher
2859 than the priority of ABOVETHIS."""
2860 self.tk.call(
2861 self._w, 'tag', 'raise', tagName, aboveThis)
2862 def tag_ranges(self, tagName):
2863 """Return a list of ranges of text which have tag TAGNAME."""
2864 return self.tk.splitlist(self.tk.call(
2865 self._w, 'tag', 'ranges', tagName))
2866 def tag_remove(self, tagName, index1, index2=None):
2867 """Remove tag TAGNAME from all characters between INDEX1 and INDEX2."""
2868 self.tk.call(
2869 self._w, 'tag', 'remove', tagName, index1, index2)
2870 def window_cget(self, index, option):
2871 """Return the value of OPTION of an embedded window at INDEX."""
2872 if option[:1] != '-':
2873 option = '-' + option
2874 if option[-1:] == '_':
2875 option = option[:-1]
2876 return self.tk.call(self._w, 'window', 'cget', index, option)
2877 def window_configure(self, index, cnf={}, **kw):
2878 """Configure an embedded window at INDEX."""
2879 if type(cnf) == StringType:
2880 x = self.tk.split(self.tk.call(
2881 self._w, 'window', 'configure',
2882 index, '-'+cnf))
2883 return (x[0][1:],) + x[1:]
2884 self.tk.call(
2885 (self._w, 'window', 'configure', index)
2886 + self._options(cnf, kw))
2887 window_config = window_configure
2888 def window_create(self, index, cnf={}, **kw):
2889 """Create a window at INDEX."""
2890 self.tk.call(
2891 (self._w, 'window', 'create', index)
2892 + self._options(cnf, kw))
2893 def window_names(self):
2894 """Return all names of embedded windows in this widget."""
2895 return self.tk.splitlist(
2896 self.tk.call(self._w, 'window', 'names'))
2897 def xview(self, *what):
2898 """Query and change horizontal position of the view."""
2899 if not what:
2900 return self._getdoubles(self.tk.call(self._w, 'xview'))
2901 self.tk.call((self._w, 'xview') + what)
Fredrik Lundh5bd2cd62000-08-09 18:29:51 +00002902 def xview_moveto(self, fraction):
2903 """Adjusts the view in the window so that FRACTION of the
2904 total width of the canvas is off-screen to the left."""
2905 self.tk.call(self._w, 'xview', 'moveto', fraction)
2906 def xview_scroll(self, number, what):
2907 """Shift the x-view according to NUMBER which is measured
2908 in "units" or "pages" (WHAT)."""
2909 self.tk.call(self._w, 'xview', 'scroll', number, what)
Fredrik Lundh8fffa202000-08-09 18:51:01 +00002910 def yview(self, *what):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002911 """Query and change vertical position of the view."""
Fredrik Lundh8fffa202000-08-09 18:51:01 +00002912 if not what:
Fredrik Lundh06d28152000-08-09 18:03:12 +00002913 return self._getdoubles(self.tk.call(self._w, 'yview'))
Fredrik Lundh8fffa202000-08-09 18:51:01 +00002914 self.tk.call((self._w, 'yview') + what)
Fredrik Lundh5bd2cd62000-08-09 18:29:51 +00002915 def yview_moveto(self, fraction):
2916 """Adjusts the view in the window so that FRACTION of the
2917 total height of the canvas is off-screen to the top."""
2918 self.tk.call(self._w, 'yview', 'moveto', fraction)
2919 def yview_scroll(self, number, what):
2920 """Shift the y-view according to NUMBER which is measured
2921 in "units" or "pages" (WHAT)."""
2922 self.tk.call(self._w, 'yview', 'scroll', number, what)
Fredrik Lundh06d28152000-08-09 18:03:12 +00002923 def yview_pickplace(self, *what):
2924 """Obsolete function, use see."""
2925 self.tk.call((self._w, 'yview', '-pickplace') + what)
Guido van Rossum18468821994-06-20 07:49:28 +00002926
Guido van Rossum28574b51996-10-21 15:16:51 +00002927class _setit:
Fredrik Lundh06d28152000-08-09 18:03:12 +00002928 """Internal class. It wraps the command in the widget OptionMenu."""
2929 def __init__(self, var, value, callback=None):
2930 self.__value = value
2931 self.__var = var
2932 self.__callback = callback
2933 def __call__(self, *args):
2934 self.__var.set(self.__value)
2935 if self.__callback:
2936 apply(self.__callback, (self.__value,)+args)
Guido van Rossum28574b51996-10-21 15:16:51 +00002937
2938class OptionMenu(Menubutton):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002939 """OptionMenu which allows the user to select a value from a menu."""
2940 def __init__(self, master, variable, value, *values, **kwargs):
2941 """Construct an optionmenu widget with the parent MASTER, with
2942 the resource textvariable set to VARIABLE, the initially selected
2943 value VALUE, the other menu values VALUES and an additional
2944 keyword argument command."""
2945 kw = {"borderwidth": 2, "textvariable": variable,
2946 "indicatoron": 1, "relief": RAISED, "anchor": "c",
2947 "highlightthickness": 2}
2948 Widget.__init__(self, master, "menubutton", kw)
2949 self.widgetName = 'tk_optionMenu'
2950 menu = self.__menu = Menu(self, name="menu", tearoff=0)
2951 self.menuname = menu._w
2952 # 'command' is the only supported keyword
2953 callback = kwargs.get('command')
2954 if kwargs.has_key('command'):
2955 del kwargs['command']
2956 if kwargs:
2957 raise TclError, 'unknown option -'+kwargs.keys()[0]
2958 menu.add_command(label=value,
2959 command=_setit(variable, value, callback))
2960 for v in values:
2961 menu.add_command(label=v,
2962 command=_setit(variable, v, callback))
2963 self["menu"] = menu
Guido van Rossum28574b51996-10-21 15:16:51 +00002964
Fredrik Lundh06d28152000-08-09 18:03:12 +00002965 def __getitem__(self, name):
2966 if name == 'menu':
2967 return self.__menu
2968 return Widget.__getitem__(self, name)
Guido van Rossum28574b51996-10-21 15:16:51 +00002969
Fredrik Lundh06d28152000-08-09 18:03:12 +00002970 def destroy(self):
2971 """Destroy this widget and the associated menu."""
2972 Menubutton.destroy(self)
2973 self.__menu = None
Guido van Rossumbf4d8f91995-09-01 20:35:37 +00002974
Guido van Rossum35f67fb1995-08-04 03:50:29 +00002975class Image:
Fredrik Lundh06d28152000-08-09 18:03:12 +00002976 """Base class for images."""
Martin v. Löwis0d8ce612000-09-08 16:28:30 +00002977 _last_id = 0
Fredrik Lundh06d28152000-08-09 18:03:12 +00002978 def __init__(self, imgtype, name=None, cnf={}, master=None, **kw):
2979 self.name = None
2980 if not master:
2981 master = _default_root
2982 if not master:
2983 raise RuntimeError, 'Too early to create image'
2984 self.tk = master.tk
2985 if not name:
Martin v. Löwis0d8ce612000-09-08 16:28:30 +00002986 Image._last_id += 1
2987 name = "pyimage" +`Image._last_id` # tk itself would use image<x>
Fredrik Lundh06d28152000-08-09 18:03:12 +00002988 # The following is needed for systems where id(x)
2989 # can return a negative number, such as Linux/m68k:
2990 if name[0] == '-': name = '_' + name[1:]
2991 if kw and cnf: cnf = _cnfmerge((cnf, kw))
2992 elif kw: cnf = kw
2993 options = ()
2994 for k, v in cnf.items():
2995 if callable(v):
2996 v = self._register(v)
2997 options = options + ('-'+k, v)
2998 self.tk.call(('image', 'create', imgtype, name,) + options)
2999 self.name = name
3000 def __str__(self): return self.name
3001 def __del__(self):
3002 if self.name:
3003 try:
3004 self.tk.call('image', 'delete', self.name)
3005 except TclError:
3006 # May happen if the root was destroyed
3007 pass
3008 def __setitem__(self, key, value):
3009 self.tk.call(self.name, 'configure', '-'+key, value)
3010 def __getitem__(self, key):
3011 return self.tk.call(self.name, 'configure', '-'+key)
3012 def configure(self, **kw):
3013 """Configure the image."""
3014 res = ()
3015 for k, v in _cnfmerge(kw).items():
3016 if v is not None:
3017 if k[-1] == '_': k = k[:-1]
3018 if callable(v):
3019 v = self._register(v)
3020 res = res + ('-'+k, v)
3021 self.tk.call((self.name, 'config') + res)
3022 config = configure
3023 def height(self):
3024 """Return the height of the image."""
3025 return getint(
3026 self.tk.call('image', 'height', self.name))
3027 def type(self):
3028 """Return the type of the imgage, e.g. "photo" or "bitmap"."""
3029 return self.tk.call('image', 'type', self.name)
3030 def width(self):
3031 """Return the width of the image."""
3032 return getint(
3033 self.tk.call('image', 'width', self.name))
Guido van Rossum35f67fb1995-08-04 03:50:29 +00003034
3035class PhotoImage(Image):
Fredrik Lundh06d28152000-08-09 18:03:12 +00003036 """Widget which can display colored images in GIF, PPM/PGM format."""
3037 def __init__(self, name=None, cnf={}, master=None, **kw):
3038 """Create an image with NAME.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00003039
Fredrik Lundh06d28152000-08-09 18:03:12 +00003040 Valid resource names: data, format, file, gamma, height, palette,
3041 width."""
3042 apply(Image.__init__, (self, 'photo', name, cnf, master), kw)
3043 def blank(self):
3044 """Display a transparent image."""
3045 self.tk.call(self.name, 'blank')
3046 def cget(self, option):
3047 """Return the value of OPTION."""
3048 return self.tk.call(self.name, 'cget', '-' + option)
3049 # XXX config
3050 def __getitem__(self, key):
3051 return self.tk.call(self.name, 'cget', '-' + key)
3052 # XXX copy -from, -to, ...?
3053 def copy(self):
3054 """Return a new PhotoImage with the same image as this widget."""
3055 destImage = PhotoImage()
3056 self.tk.call(destImage, 'copy', self.name)
3057 return destImage
3058 def zoom(self,x,y=''):
3059 """Return a new PhotoImage with the same image as this widget
3060 but zoom it with X and Y."""
3061 destImage = PhotoImage()
3062 if y=='': y=x
3063 self.tk.call(destImage, 'copy', self.name, '-zoom',x,y)
3064 return destImage
3065 def subsample(self,x,y=''):
3066 """Return a new PhotoImage based on the same image as this widget
3067 but use only every Xth or Yth pixel."""
3068 destImage = PhotoImage()
3069 if y=='': y=x
3070 self.tk.call(destImage, 'copy', self.name, '-subsample',x,y)
3071 return destImage
3072 def get(self, x, y):
3073 """Return the color (red, green, blue) of the pixel at X,Y."""
3074 return self.tk.call(self.name, 'get', x, y)
3075 def put(self, data, to=None):
3076 """Put row formated colors to image starting from
3077 position TO, e.g. image.put("{red green} {blue yellow}", to=(4,6))"""
3078 args = (self.name, 'put', data)
3079 if to:
3080 if to[0] == '-to':
3081 to = to[1:]
3082 args = args + ('-to',) + tuple(to)
3083 self.tk.call(args)
3084 # XXX read
3085 def write(self, filename, format=None, from_coords=None):
3086 """Write image to file FILENAME in FORMAT starting from
3087 position FROM_COORDS."""
3088 args = (self.name, 'write', filename)
3089 if format:
3090 args = args + ('-format', format)
3091 if from_coords:
3092 args = args + ('-from',) + tuple(from_coords)
3093 self.tk.call(args)
Guido van Rossum35f67fb1995-08-04 03:50:29 +00003094
3095class BitmapImage(Image):
Fredrik Lundh06d28152000-08-09 18:03:12 +00003096 """Widget which can display a bitmap."""
3097 def __init__(self, name=None, cnf={}, master=None, **kw):
3098 """Create a bitmap with NAME.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00003099
Fredrik Lundh06d28152000-08-09 18:03:12 +00003100 Valid resource names: background, data, file, foreground, maskdata, maskfile."""
3101 apply(Image.__init__, (self, 'bitmap', name, cnf, master), kw)
Guido van Rossum35f67fb1995-08-04 03:50:29 +00003102
3103def image_names(): return _default_root.tk.call('image', 'names')
3104def image_types(): return _default_root.tk.call('image', 'types')
3105
Guido van Rossumaec5dc91994-06-27 07:55:12 +00003106######################################################################
3107# Extensions:
3108
3109class Studbutton(Button):
Fredrik Lundh06d28152000-08-09 18:03:12 +00003110 def __init__(self, master=None, cnf={}, **kw):
3111 Widget.__init__(self, master, 'studbutton', cnf, kw)
3112 self.bind('<Any-Enter>', self.tkButtonEnter)
3113 self.bind('<Any-Leave>', self.tkButtonLeave)
3114 self.bind('<1>', self.tkButtonDown)
3115 self.bind('<ButtonRelease-1>', self.tkButtonUp)
Guido van Rossumaec5dc91994-06-27 07:55:12 +00003116
3117class Tributton(Button):
Fredrik Lundh06d28152000-08-09 18:03:12 +00003118 def __init__(self, master=None, cnf={}, **kw):
3119 Widget.__init__(self, master, 'tributton', cnf, kw)
3120 self.bind('<Any-Enter>', self.tkButtonEnter)
3121 self.bind('<Any-Leave>', self.tkButtonLeave)
3122 self.bind('<1>', self.tkButtonDown)
3123 self.bind('<ButtonRelease-1>', self.tkButtonUp)
3124 self['fg'] = self['bg']
3125 self['activebackground'] = self['bg']
Guido van Rossum37dcab11996-05-16 16:00:19 +00003126
Guido van Rossumc417ef81996-08-21 23:38:59 +00003127######################################################################
3128# Test:
3129
3130def _test():
Fredrik Lundh06d28152000-08-09 18:03:12 +00003131 root = Tk()
3132 text = "This is Tcl/Tk version %s" % TclVersion
3133 if TclVersion >= 8.1:
Fredrik Lundh8fffa202000-08-09 18:51:01 +00003134 try:
3135 text = text + unicode("\nThis should be a cedilla: \347",
3136 "iso-8859-1")
3137 except NameError:
3138 pass # no unicode support
Fredrik Lundh06d28152000-08-09 18:03:12 +00003139 label = Label(root, text=text)
3140 label.pack()
3141 test = Button(root, text="Click me!",
3142 command=lambda root=root: root.test.configure(
3143 text="[%s]" % root.test['text']))
3144 test.pack()
3145 root.test = test
3146 quit = Button(root, text="QUIT", command=root.destroy)
3147 quit.pack()
3148 # The following three commands are needed so the window pops
3149 # up on top on Windows...
3150 root.iconify()
3151 root.update()
3152 root.deiconify()
3153 root.mainloop()
Guido van Rossumc417ef81996-08-21 23:38:59 +00003154
3155if __name__ == '__main__':
Fredrik Lundh06d28152000-08-09 18:03:12 +00003156 _test()