blob: f2c9a91c72224ed243e05233c3ede121f9f640b3 [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)
Martin v. Löwis6ce13152002-10-10 14:36:13 +00001070 def _configure(self, cmd, cnf, kw):
1071 """Internal function."""
1072 if kw:
1073 cnf = _cnfmerge((cnf, kw))
1074 elif cnf:
1075 cnf = _cnfmerge(cnf)
1076 if cnf is None:
1077 cnf = {}
1078 for x in self.tk.split(
1079 self.tk.call(_flatten((self._w, cmd)))):
1080 cnf[x[0][1:]] = (x[0][1:],) + x[1:]
1081 return cnf
1082 if type(cnf) is StringType:
1083 x = self.tk.split(
1084 self.tk.call(_flatten((self._w, cmd, '-'+cnf))))
1085 return (x[0][1:],) + x[1:]
1086 self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
Fredrik Lundh06d28152000-08-09 18:03:12 +00001087 # These used to be defined in Widget:
1088 def configure(self, cnf=None, **kw):
1089 """Configure resources of a widget.
Barry Warsaw107e6231998-12-15 00:44:15 +00001090
Fredrik Lundh06d28152000-08-09 18:03:12 +00001091 The values for resources are specified as keyword
1092 arguments. To get an overview about
1093 the allowed keyword arguments call the method keys.
1094 """
Martin v. Löwis6ce13152002-10-10 14:36:13 +00001095 return self._configure('configure', cnf, kw)
Fredrik Lundh06d28152000-08-09 18:03:12 +00001096 config = configure
1097 def cget(self, key):
1098 """Return the resource value for a KEY given as string."""
1099 return self.tk.call(self._w, 'cget', '-' + key)
1100 __getitem__ = cget
1101 def __setitem__(self, key, value):
1102 self.configure({key: value})
1103 def keys(self):
1104 """Return a list of all resource names of this widget."""
1105 return map(lambda x: x[0][1:],
1106 self.tk.split(self.tk.call(self._w, 'configure')))
1107 def __str__(self):
1108 """Return the window path name of this widget."""
1109 return self._w
1110 # Pack methods that apply to the master
1111 _noarg_ = ['_noarg_']
1112 def pack_propagate(self, flag=_noarg_):
1113 """Set or get the status for propagation of geometry information.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001114
Fredrik Lundh06d28152000-08-09 18:03:12 +00001115 A boolean argument specifies whether the geometry information
1116 of the slaves will determine the size of this widget. If no argument
1117 is given the current setting will be returned.
1118 """
1119 if flag is Misc._noarg_:
1120 return self._getboolean(self.tk.call(
1121 'pack', 'propagate', self._w))
1122 else:
1123 self.tk.call('pack', 'propagate', self._w, flag)
1124 propagate = pack_propagate
1125 def pack_slaves(self):
1126 """Return a list of all slaves of this widget
1127 in its packing order."""
1128 return map(self._nametowidget,
1129 self.tk.splitlist(
1130 self.tk.call('pack', 'slaves', self._w)))
1131 slaves = pack_slaves
1132 # Place method that applies to the master
1133 def place_slaves(self):
1134 """Return a list of all slaves of this widget
1135 in its packing order."""
1136 return map(self._nametowidget,
1137 self.tk.splitlist(
1138 self.tk.call(
1139 'place', 'slaves', self._w)))
1140 # Grid methods that apply to the master
1141 def grid_bbox(self, column=None, row=None, col2=None, row2=None):
1142 """Return a tuple of integer coordinates for the bounding
1143 box of this widget controlled by the geometry manager grid.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001144
Fredrik Lundh06d28152000-08-09 18:03:12 +00001145 If COLUMN, ROW is given the bounding box applies from
1146 the cell with row and column 0 to the specified
1147 cell. If COL2 and ROW2 are given the bounding box
1148 starts at that cell.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001149
Fredrik Lundh06d28152000-08-09 18:03:12 +00001150 The returned integers specify the offset of the upper left
1151 corner in the master widget and the width and height.
1152 """
1153 args = ('grid', 'bbox', self._w)
1154 if column is not None and row is not None:
1155 args = args + (column, row)
1156 if col2 is not None and row2 is not None:
1157 args = args + (col2, row2)
1158 return self._getints(apply(self.tk.call, args)) or None
Guido van Rossum18468821994-06-20 07:49:28 +00001159
Fredrik Lundh06d28152000-08-09 18:03:12 +00001160 bbox = grid_bbox
1161 def _grid_configure(self, command, index, cnf, kw):
1162 """Internal function."""
1163 if type(cnf) is StringType and not kw:
1164 if cnf[-1:] == '_':
1165 cnf = cnf[:-1]
1166 if cnf[:1] != '-':
1167 cnf = '-'+cnf
1168 options = (cnf,)
1169 else:
1170 options = self._options(cnf, kw)
1171 if not options:
1172 res = self.tk.call('grid',
1173 command, self._w, index)
1174 words = self.tk.splitlist(res)
1175 dict = {}
1176 for i in range(0, len(words), 2):
1177 key = words[i][1:]
1178 value = words[i+1]
1179 if not value:
1180 value = None
1181 elif '.' in value:
1182 value = getdouble(value)
1183 else:
1184 value = getint(value)
1185 dict[key] = value
1186 return dict
1187 res = self.tk.call(
1188 ('grid', command, self._w, index)
1189 + options)
1190 if len(options) == 1:
1191 if not res: return None
1192 # In Tk 7.5, -width can be a float
1193 if '.' in res: return getdouble(res)
1194 return getint(res)
1195 def grid_columnconfigure(self, index, cnf={}, **kw):
1196 """Configure column INDEX of a grid.
Guido van Rossum80f8be81997-12-02 19:51:39 +00001197
Fredrik Lundh06d28152000-08-09 18:03:12 +00001198 Valid resources are minsize (minimum size of the column),
1199 weight (how much does additional space propagate to this column)
1200 and pad (how much space to let additionally)."""
1201 return self._grid_configure('columnconfigure', index, cnf, kw)
1202 columnconfigure = grid_columnconfigure
Martin v. Löwisdc579092001-10-13 09:33:51 +00001203 def grid_location(self, x, y):
1204 """Return a tuple of column and row which identify the cell
1205 at which the pixel at position X and Y inside the master
1206 widget is located."""
1207 return self._getints(
1208 self.tk.call(
1209 'grid', 'location', self._w, x, y)) or None
Fredrik Lundh06d28152000-08-09 18:03:12 +00001210 def grid_propagate(self, flag=_noarg_):
1211 """Set or get the status for propagation of geometry information.
Guido van Rossum80f8be81997-12-02 19:51:39 +00001212
Fredrik Lundh06d28152000-08-09 18:03:12 +00001213 A boolean argument specifies whether the geometry information
1214 of the slaves will determine the size of this widget. If no argument
1215 is given, the current setting will be returned.
1216 """
1217 if flag is Misc._noarg_:
1218 return self._getboolean(self.tk.call(
1219 'grid', 'propagate', self._w))
1220 else:
1221 self.tk.call('grid', 'propagate', self._w, flag)
1222 def grid_rowconfigure(self, index, cnf={}, **kw):
1223 """Configure row INDEX of a grid.
Guido van Rossum80f8be81997-12-02 19:51:39 +00001224
Fredrik Lundh06d28152000-08-09 18:03:12 +00001225 Valid resources are minsize (minimum size of the row),
1226 weight (how much does additional space propagate to this row)
1227 and pad (how much space to let additionally)."""
1228 return self._grid_configure('rowconfigure', index, cnf, kw)
1229 rowconfigure = grid_rowconfigure
1230 def grid_size(self):
1231 """Return a tuple of the number of column and rows in the grid."""
1232 return self._getints(
1233 self.tk.call('grid', 'size', self._w)) or None
1234 size = grid_size
1235 def grid_slaves(self, row=None, column=None):
1236 """Return a list of all slaves of this widget
1237 in its packing order."""
1238 args = ()
1239 if row is not None:
1240 args = args + ('-row', row)
1241 if column is not None:
1242 args = args + ('-column', column)
1243 return map(self._nametowidget,
1244 self.tk.splitlist(self.tk.call(
1245 ('grid', 'slaves', self._w) + args)))
Guido van Rossum80f8be81997-12-02 19:51:39 +00001246
Fredrik Lundh06d28152000-08-09 18:03:12 +00001247 # Support for the "event" command, new in Tk 4.2.
1248 # By Case Roole.
Guido van Rossum80f8be81997-12-02 19:51:39 +00001249
Fredrik Lundh06d28152000-08-09 18:03:12 +00001250 def event_add(self, virtual, *sequences):
1251 """Bind a virtual event VIRTUAL (of the form <<Name>>)
1252 to an event SEQUENCE such that the virtual event is triggered
1253 whenever SEQUENCE occurs."""
1254 args = ('event', 'add', virtual) + sequences
1255 self.tk.call(args)
Guido van Rossumc2966511998-04-10 19:16:10 +00001256
Fredrik Lundh06d28152000-08-09 18:03:12 +00001257 def event_delete(self, virtual, *sequences):
1258 """Unbind a virtual event VIRTUAL from SEQUENCE."""
1259 args = ('event', 'delete', virtual) + sequences
1260 self.tk.call(args)
Guido van Rossumc2966511998-04-10 19:16:10 +00001261
Fredrik Lundh06d28152000-08-09 18:03:12 +00001262 def event_generate(self, sequence, **kw):
1263 """Generate an event SEQUENCE. Additional
1264 keyword arguments specify parameter of the event
1265 (e.g. x, y, rootx, rooty)."""
1266 args = ('event', 'generate', self._w, sequence)
1267 for k, v in kw.items():
1268 args = args + ('-%s' % k, str(v))
1269 self.tk.call(args)
1270
1271 def event_info(self, virtual=None):
1272 """Return a list of all virtual events or the information
1273 about the SEQUENCE bound to the virtual event VIRTUAL."""
1274 return self.tk.splitlist(
1275 self.tk.call('event', 'info', virtual))
1276
1277 # Image related commands
1278
1279 def image_names(self):
1280 """Return a list of all existing image names."""
1281 return self.tk.call('image', 'names')
1282
1283 def image_types(self):
1284 """Return a list of all available image types (e.g. phote bitmap)."""
1285 return self.tk.call('image', 'types')
Guido van Rossumc2966511998-04-10 19:16:10 +00001286
Guido van Rossum80f8be81997-12-02 19:51:39 +00001287
Guido van Rossuma5773dd1995-09-07 19:22:00 +00001288class CallWrapper:
Fredrik Lundh06d28152000-08-09 18:03:12 +00001289 """Internal class. Stores function to call when some user
1290 defined Tcl function is called e.g. after an event occurred."""
1291 def __init__(self, func, subst, widget):
1292 """Store FUNC, SUBST and WIDGET as members."""
1293 self.func = func
1294 self.subst = subst
1295 self.widget = widget
1296 def __call__(self, *args):
1297 """Apply first function SUBST to arguments, than FUNC."""
1298 try:
1299 if self.subst:
1300 args = apply(self.subst, args)
1301 return apply(self.func, args)
1302 except SystemExit, msg:
1303 raise SystemExit, msg
1304 except:
1305 self.widget._report_exception()
Guido van Rossum18468821994-06-20 07:49:28 +00001306
Guido van Rossume365a591998-05-01 19:48:20 +00001307
Guido van Rossum18468821994-06-20 07:49:28 +00001308class Wm:
Fredrik Lundh06d28152000-08-09 18:03:12 +00001309 """Provides functions for the communication with the window manager."""
1310 def wm_aspect(self,
1311 minNumer=None, minDenom=None,
1312 maxNumer=None, maxDenom=None):
1313 """Instruct the window manager to set the aspect ratio (width/height)
1314 of this widget to be between MINNUMER/MINDENOM and MAXNUMER/MAXDENOM. Return a tuple
1315 of the actual values if no argument is given."""
1316 return self._getints(
1317 self.tk.call('wm', 'aspect', self._w,
1318 minNumer, minDenom,
1319 maxNumer, maxDenom))
1320 aspect = wm_aspect
1321 def wm_client(self, name=None):
1322 """Store NAME in WM_CLIENT_MACHINE property of this widget. Return
1323 current value."""
1324 return self.tk.call('wm', 'client', self._w, name)
1325 client = wm_client
1326 def wm_colormapwindows(self, *wlist):
1327 """Store list of window names (WLIST) into WM_COLORMAPWINDOWS property
1328 of this widget. This list contains windows whose colormaps differ from their
1329 parents. Return current list of widgets if WLIST is empty."""
1330 if len(wlist) > 1:
1331 wlist = (wlist,) # Tk needs a list of windows here
1332 args = ('wm', 'colormapwindows', self._w) + wlist
1333 return map(self._nametowidget, self.tk.call(args))
1334 colormapwindows = wm_colormapwindows
1335 def wm_command(self, value=None):
1336 """Store VALUE in WM_COMMAND property. It is the command
1337 which shall be used to invoke the application. Return current
1338 command if VALUE is None."""
1339 return self.tk.call('wm', 'command', self._w, value)
1340 command = wm_command
1341 def wm_deiconify(self):
1342 """Deiconify this widget. If it was never mapped it will not be mapped.
1343 On Windows it will raise this widget and give it the focus."""
1344 return self.tk.call('wm', 'deiconify', self._w)
1345 deiconify = wm_deiconify
1346 def wm_focusmodel(self, model=None):
1347 """Set focus model to MODEL. "active" means that this widget will claim
1348 the focus itself, "passive" means that the window manager shall give
1349 the focus. Return current focus model if MODEL is None."""
1350 return self.tk.call('wm', 'focusmodel', self._w, model)
1351 focusmodel = wm_focusmodel
1352 def wm_frame(self):
1353 """Return identifier for decorative frame of this widget if present."""
1354 return self.tk.call('wm', 'frame', self._w)
1355 frame = wm_frame
1356 def wm_geometry(self, newGeometry=None):
1357 """Set geometry to NEWGEOMETRY of the form =widthxheight+x+y. Return
1358 current value if None is given."""
1359 return self.tk.call('wm', 'geometry', self._w, newGeometry)
1360 geometry = wm_geometry
1361 def wm_grid(self,
1362 baseWidth=None, baseHeight=None,
1363 widthInc=None, heightInc=None):
1364 """Instruct the window manager that this widget shall only be
1365 resized on grid boundaries. WIDTHINC and HEIGHTINC are the width and
1366 height of a grid unit in pixels. BASEWIDTH and BASEHEIGHT are the
1367 number of grid units requested in Tk_GeometryRequest."""
1368 return self._getints(self.tk.call(
1369 'wm', 'grid', self._w,
1370 baseWidth, baseHeight, widthInc, heightInc))
1371 grid = wm_grid
1372 def wm_group(self, pathName=None):
1373 """Set the group leader widgets for related widgets to PATHNAME. Return
1374 the group leader of this widget if None is given."""
1375 return self.tk.call('wm', 'group', self._w, pathName)
1376 group = wm_group
1377 def wm_iconbitmap(self, bitmap=None):
1378 """Set bitmap for the iconified widget to BITMAP. Return
1379 the bitmap if None is given."""
1380 return self.tk.call('wm', 'iconbitmap', self._w, bitmap)
1381 iconbitmap = wm_iconbitmap
1382 def wm_iconify(self):
1383 """Display widget as icon."""
1384 return self.tk.call('wm', 'iconify', self._w)
1385 iconify = wm_iconify
1386 def wm_iconmask(self, bitmap=None):
1387 """Set mask for the icon bitmap of this widget. Return the
1388 mask if None is given."""
1389 return self.tk.call('wm', 'iconmask', self._w, bitmap)
1390 iconmask = wm_iconmask
1391 def wm_iconname(self, newName=None):
1392 """Set the name of the icon for this widget. Return the name if
1393 None is given."""
1394 return self.tk.call('wm', 'iconname', self._w, newName)
1395 iconname = wm_iconname
1396 def wm_iconposition(self, x=None, y=None):
1397 """Set the position of the icon of this widget to X and Y. Return
1398 a tuple of the current values of X and X if None is given."""
1399 return self._getints(self.tk.call(
1400 'wm', 'iconposition', self._w, x, y))
1401 iconposition = wm_iconposition
1402 def wm_iconwindow(self, pathName=None):
1403 """Set widget PATHNAME to be displayed instead of icon. Return the current
1404 value if None is given."""
1405 return self.tk.call('wm', 'iconwindow', self._w, pathName)
1406 iconwindow = wm_iconwindow
1407 def wm_maxsize(self, width=None, height=None):
1408 """Set max WIDTH and HEIGHT for this widget. If the window is gridded
1409 the values are given in grid units. Return the current values if None
1410 is given."""
1411 return self._getints(self.tk.call(
1412 'wm', 'maxsize', self._w, width, height))
1413 maxsize = wm_maxsize
1414 def wm_minsize(self, width=None, height=None):
1415 """Set min WIDTH and HEIGHT for this widget. If the window is gridded
1416 the values are given in grid units. Return the current values if None
1417 is given."""
1418 return self._getints(self.tk.call(
1419 'wm', 'minsize', self._w, width, height))
1420 minsize = wm_minsize
1421 def wm_overrideredirect(self, boolean=None):
1422 """Instruct the window manager to ignore this widget
1423 if BOOLEAN is given with 1. Return the current value if None
1424 is given."""
1425 return self._getboolean(self.tk.call(
1426 'wm', 'overrideredirect', self._w, boolean))
1427 overrideredirect = wm_overrideredirect
1428 def wm_positionfrom(self, who=None):
1429 """Instruct the window manager that the position of this widget shall
1430 be defined by the user if WHO is "user", and by its own policy if WHO is
1431 "program"."""
1432 return self.tk.call('wm', 'positionfrom', self._w, who)
1433 positionfrom = wm_positionfrom
1434 def wm_protocol(self, name=None, func=None):
1435 """Bind function FUNC to command NAME for this widget.
1436 Return the function bound to NAME if None is given. NAME could be
1437 e.g. "WM_SAVE_YOURSELF" or "WM_DELETE_WINDOW"."""
1438 if callable(func):
1439 command = self._register(func)
1440 else:
1441 command = func
1442 return self.tk.call(
1443 'wm', 'protocol', self._w, name, command)
1444 protocol = wm_protocol
1445 def wm_resizable(self, width=None, height=None):
1446 """Instruct the window manager whether this width can be resized
1447 in WIDTH or HEIGHT. Both values are boolean values."""
1448 return self.tk.call('wm', 'resizable', self._w, width, height)
1449 resizable = wm_resizable
1450 def wm_sizefrom(self, who=None):
1451 """Instruct the window manager that the size of this widget shall
1452 be defined by the user if WHO is "user", and by its own policy if WHO is
1453 "program"."""
1454 return self.tk.call('wm', 'sizefrom', self._w, who)
1455 sizefrom = wm_sizefrom
Fredrik Lundh289ad8f2000-08-09 19:11:59 +00001456 def wm_state(self, newstate=None):
1457 """Query or set the state of this widget as one of normal, icon,
1458 iconic (see wm_iconwindow), withdrawn, or zoomed (Windows only)."""
1459 return self.tk.call('wm', 'state', self._w, newstate)
Fredrik Lundh06d28152000-08-09 18:03:12 +00001460 state = wm_state
1461 def wm_title(self, string=None):
1462 """Set the title of this widget."""
1463 return self.tk.call('wm', 'title', self._w, string)
1464 title = wm_title
1465 def wm_transient(self, master=None):
1466 """Instruct the window manager that this widget is transient
1467 with regard to widget MASTER."""
1468 return self.tk.call('wm', 'transient', self._w, master)
1469 transient = wm_transient
1470 def wm_withdraw(self):
1471 """Withdraw this widget from the screen such that it is unmapped
1472 and forgotten by the window manager. Re-draw it with wm_deiconify."""
1473 return self.tk.call('wm', 'withdraw', self._w)
1474 withdraw = wm_withdraw
Guido van Rossume365a591998-05-01 19:48:20 +00001475
Guido van Rossum18468821994-06-20 07:49:28 +00001476
1477class Tk(Misc, Wm):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001478 """Toplevel widget of Tk which represents mostly the main window
1479 of an appliation. It has an associated Tcl interpreter."""
1480 _w = '.'
1481 def __init__(self, screenName=None, baseName=None, className='Tk'):
1482 """Return a new Toplevel widget on screen SCREENNAME. A new Tcl interpreter will
1483 be created. BASENAME will be used for the identification of the profile file (see
1484 readprofile).
1485 It is constructed from sys.argv[0] without extensions if None is given. CLASSNAME
1486 is the name of the widget class."""
1487 global _default_root
1488 self.master = None
1489 self.children = {}
1490 if baseName is None:
1491 import sys, os
1492 baseName = os.path.basename(sys.argv[0])
1493 baseName, ext = os.path.splitext(baseName)
1494 if ext not in ('.py', '.pyc', '.pyo'):
1495 baseName = baseName + ext
1496 self.tk = _tkinter.create(screenName, baseName, className)
Jack Jansenbe92af02001-08-23 13:25:59 +00001497 if _MacOS and hasattr(_MacOS, 'SchedParams'):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001498 # Disable event scanning except for Command-Period
1499 _MacOS.SchedParams(1, 0)
1500 # Work around nasty MacTk bug
1501 # XXX Is this one still needed?
1502 self.update()
1503 # Version sanity checks
1504 tk_version = self.tk.getvar('tk_version')
1505 if tk_version != _tkinter.TK_VERSION:
1506 raise RuntimeError, \
1507 "tk.h version (%s) doesn't match libtk.a version (%s)" \
1508 % (_tkinter.TK_VERSION, tk_version)
1509 tcl_version = self.tk.getvar('tcl_version')
1510 if tcl_version != _tkinter.TCL_VERSION:
1511 raise RuntimeError, \
1512 "tcl.h version (%s) doesn't match libtcl.a version (%s)" \
1513 % (_tkinter.TCL_VERSION, tcl_version)
1514 if TkVersion < 4.0:
1515 raise RuntimeError, \
1516 "Tk 4.0 or higher is required; found Tk %s" \
1517 % str(TkVersion)
1518 self.tk.createcommand('tkerror', _tkerror)
1519 self.tk.createcommand('exit', _exit)
1520 self.readprofile(baseName, className)
1521 if _support_default_root and not _default_root:
1522 _default_root = self
1523 self.protocol("WM_DELETE_WINDOW", self.destroy)
1524 def destroy(self):
1525 """Destroy this and all descendants widgets. This will
1526 end the application of this Tcl interpreter."""
1527 for c in self.children.values(): c.destroy()
1528 self.tk.call('destroy', self._w)
1529 Misc.destroy(self)
1530 global _default_root
1531 if _support_default_root and _default_root is self:
1532 _default_root = None
1533 def readprofile(self, baseName, className):
1534 """Internal function. It reads BASENAME.tcl and CLASSNAME.tcl into
1535 the Tcl Interpreter and calls execfile on BASENAME.py and CLASSNAME.py if
1536 such a file exists in the home directory."""
1537 import os
1538 if os.environ.has_key('HOME'): home = os.environ['HOME']
1539 else: home = os.curdir
1540 class_tcl = os.path.join(home, '.%s.tcl' % className)
1541 class_py = os.path.join(home, '.%s.py' % className)
1542 base_tcl = os.path.join(home, '.%s.tcl' % baseName)
1543 base_py = os.path.join(home, '.%s.py' % baseName)
1544 dir = {'self': self}
1545 exec 'from Tkinter import *' in dir
1546 if os.path.isfile(class_tcl):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001547 self.tk.call('source', class_tcl)
1548 if os.path.isfile(class_py):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001549 execfile(class_py, dir)
1550 if os.path.isfile(base_tcl):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001551 self.tk.call('source', base_tcl)
1552 if os.path.isfile(base_py):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001553 execfile(base_py, dir)
1554 def report_callback_exception(self, exc, val, tb):
1555 """Internal function. It reports exception on sys.stderr."""
1556 import traceback, sys
1557 sys.stderr.write("Exception in Tkinter callback\n")
1558 sys.last_type = exc
1559 sys.last_value = val
1560 sys.last_traceback = tb
1561 traceback.print_exception(exc, val, tb)
Guido van Rossum18468821994-06-20 07:49:28 +00001562
Guido van Rossum368e06b1997-11-07 20:38:49 +00001563# Ideally, the classes Pack, Place and Grid disappear, the
1564# pack/place/grid methods are defined on the Widget class, and
1565# everybody uses w.pack_whatever(...) instead of Pack.whatever(w,
1566# ...), with pack(), place() and grid() being short for
1567# pack_configure(), place_configure() and grid_columnconfigure(), and
1568# forget() being short for pack_forget(). As a practical matter, I'm
1569# afraid that there is too much code out there that may be using the
1570# Pack, Place or Grid class, so I leave them intact -- but only as
1571# backwards compatibility features. Also note that those methods that
1572# take a master as argument (e.g. pack_propagate) have been moved to
1573# the Misc class (which now incorporates all methods common between
1574# toplevel and interior widgets). Again, for compatibility, these are
1575# copied into the Pack, Place or Grid class.
1576
Guido van Rossum18468821994-06-20 07:49:28 +00001577class Pack:
Fredrik Lundh06d28152000-08-09 18:03:12 +00001578 """Geometry manager Pack.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001579
Fredrik Lundh06d28152000-08-09 18:03:12 +00001580 Base class to use the methods pack_* in every widget."""
1581 def pack_configure(self, cnf={}, **kw):
1582 """Pack a widget in the parent widget. Use as options:
1583 after=widget - pack it after you have packed widget
1584 anchor=NSEW (or subset) - position widget according to
1585 given direction
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001586 before=widget - pack it before you will pack widget
Fredrik Lundh06d28152000-08-09 18:03:12 +00001587 expand=1 or 0 - expand widget if parent size grows
1588 fill=NONE or X or Y or BOTH - fill widget if widget grows
1589 in=master - use master to contain this widget
1590 ipadx=amount - add internal padding in x direction
1591 ipady=amount - add internal padding in y direction
1592 padx=amount - add padding in x direction
1593 pady=amount - add padding in y direction
1594 side=TOP or BOTTOM or LEFT or RIGHT - where to add this widget.
1595 """
1596 self.tk.call(
1597 ('pack', 'configure', self._w)
1598 + self._options(cnf, kw))
1599 pack = configure = config = pack_configure
1600 def pack_forget(self):
1601 """Unmap this widget and do not use it for the packing order."""
1602 self.tk.call('pack', 'forget', self._w)
1603 forget = pack_forget
1604 def pack_info(self):
1605 """Return information about the packing options
1606 for this widget."""
1607 words = self.tk.splitlist(
1608 self.tk.call('pack', 'info', self._w))
1609 dict = {}
1610 for i in range(0, len(words), 2):
1611 key = words[i][1:]
1612 value = words[i+1]
1613 if value[:1] == '.':
1614 value = self._nametowidget(value)
1615 dict[key] = value
1616 return dict
1617 info = pack_info
1618 propagate = pack_propagate = Misc.pack_propagate
1619 slaves = pack_slaves = Misc.pack_slaves
Guido van Rossum18468821994-06-20 07:49:28 +00001620
1621class Place:
Fredrik Lundh06d28152000-08-09 18:03:12 +00001622 """Geometry manager Place.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001623
Fredrik Lundh06d28152000-08-09 18:03:12 +00001624 Base class to use the methods place_* in every widget."""
1625 def place_configure(self, cnf={}, **kw):
1626 """Place a widget in the parent widget. Use as options:
1627 in=master - master relative to which the widget is placed.
1628 x=amount - locate anchor of this widget at position x of master
1629 y=amount - locate anchor of this widget at position y of master
1630 relx=amount - locate anchor of this widget between 0.0 and 1.0
1631 relative to width of master (1.0 is right edge)
1632 rely=amount - locate anchor of this widget between 0.0 and 1.0
1633 relative to height of master (1.0 is bottom edge)
1634 anchor=NSEW (or subset) - position anchor according to given direction
1635 width=amount - width of this widget in pixel
1636 height=amount - height of this widget in pixel
1637 relwidth=amount - width of this widget between 0.0 and 1.0
1638 relative to width of master (1.0 is the same width
1639 as the master)
1640 relheight=amount - height of this widget between 0.0 and 1.0
1641 relative to height of master (1.0 is the same
1642 height as the master)
1643 bordermode="inside" or "outside" - whether to take border width of master widget
1644 into account
1645 """
1646 for k in ['in_']:
1647 if kw.has_key(k):
1648 kw[k[:-1]] = kw[k]
1649 del kw[k]
1650 self.tk.call(
1651 ('place', 'configure', self._w)
1652 + self._options(cnf, kw))
1653 place = configure = config = place_configure
1654 def place_forget(self):
1655 """Unmap this widget."""
1656 self.tk.call('place', 'forget', self._w)
1657 forget = place_forget
1658 def place_info(self):
1659 """Return information about the placing options
1660 for this widget."""
1661 words = self.tk.splitlist(
1662 self.tk.call('place', 'info', self._w))
1663 dict = {}
1664 for i in range(0, len(words), 2):
1665 key = words[i][1:]
1666 value = words[i+1]
1667 if value[:1] == '.':
1668 value = self._nametowidget(value)
1669 dict[key] = value
1670 return dict
1671 info = place_info
1672 slaves = place_slaves = Misc.place_slaves
Guido van Rossum18468821994-06-20 07:49:28 +00001673
Guido van Rossum37dcab11996-05-16 16:00:19 +00001674class Grid:
Fredrik Lundh06d28152000-08-09 18:03:12 +00001675 """Geometry manager Grid.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001676
Fredrik Lundh06d28152000-08-09 18:03:12 +00001677 Base class to use the methods grid_* in every widget."""
1678 # Thanks to Masazumi Yoshikawa (yosikawa@isi.edu)
1679 def grid_configure(self, cnf={}, **kw):
1680 """Position a widget in the parent widget in a grid. Use as options:
1681 column=number - use cell identified with given column (starting with 0)
1682 columnspan=number - this widget will span several columns
1683 in=master - use master to contain this widget
1684 ipadx=amount - add internal padding in x direction
1685 ipady=amount - add internal padding in y direction
1686 padx=amount - add padding in x direction
1687 pady=amount - add padding in y direction
1688 row=number - use cell identified with given row (starting with 0)
1689 rowspan=number - this widget will span several rows
1690 sticky=NSEW - if cell is larger on which sides will this
1691 widget stick to the cell boundary
1692 """
1693 self.tk.call(
1694 ('grid', 'configure', self._w)
1695 + self._options(cnf, kw))
1696 grid = configure = config = grid_configure
1697 bbox = grid_bbox = Misc.grid_bbox
1698 columnconfigure = grid_columnconfigure = Misc.grid_columnconfigure
1699 def grid_forget(self):
1700 """Unmap this widget."""
1701 self.tk.call('grid', 'forget', self._w)
1702 forget = grid_forget
1703 def grid_remove(self):
1704 """Unmap this widget but remember the grid options."""
1705 self.tk.call('grid', 'remove', self._w)
1706 def grid_info(self):
1707 """Return information about the options
1708 for positioning this widget in a grid."""
1709 words = self.tk.splitlist(
1710 self.tk.call('grid', 'info', self._w))
1711 dict = {}
1712 for i in range(0, len(words), 2):
1713 key = words[i][1:]
1714 value = words[i+1]
1715 if value[:1] == '.':
1716 value = self._nametowidget(value)
1717 dict[key] = value
1718 return dict
1719 info = grid_info
Martin v. Löwisdc579092001-10-13 09:33:51 +00001720 location = grid_location = Misc.grid_location
Fredrik Lundh06d28152000-08-09 18:03:12 +00001721 propagate = grid_propagate = Misc.grid_propagate
1722 rowconfigure = grid_rowconfigure = Misc.grid_rowconfigure
1723 size = grid_size = Misc.grid_size
1724 slaves = grid_slaves = Misc.grid_slaves
Guido van Rossum37dcab11996-05-16 16:00:19 +00001725
Guido van Rossum368e06b1997-11-07 20:38:49 +00001726class BaseWidget(Misc):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001727 """Internal class."""
1728 def _setup(self, master, cnf):
1729 """Internal function. Sets up information about children."""
1730 if _support_default_root:
1731 global _default_root
1732 if not master:
1733 if not _default_root:
1734 _default_root = Tk()
1735 master = _default_root
1736 self.master = master
1737 self.tk = master.tk
1738 name = None
1739 if cnf.has_key('name'):
1740 name = cnf['name']
1741 del cnf['name']
1742 if not name:
1743 name = `id(self)`
1744 self._name = name
1745 if master._w=='.':
1746 self._w = '.' + name
1747 else:
1748 self._w = master._w + '.' + name
1749 self.children = {}
1750 if self.master.children.has_key(self._name):
1751 self.master.children[self._name].destroy()
1752 self.master.children[self._name] = self
1753 def __init__(self, master, widgetName, cnf={}, kw={}, extra=()):
1754 """Construct a widget with the parent widget MASTER, a name WIDGETNAME
1755 and appropriate options."""
1756 if kw:
1757 cnf = _cnfmerge((cnf, kw))
1758 self.widgetName = widgetName
1759 BaseWidget._setup(self, master, cnf)
1760 classes = []
1761 for k in cnf.keys():
1762 if type(k) is ClassType:
1763 classes.append((k, cnf[k]))
1764 del cnf[k]
1765 self.tk.call(
1766 (widgetName, self._w) + extra + self._options(cnf))
1767 for k, v in classes:
1768 k.configure(self, v)
1769 def destroy(self):
1770 """Destroy this and all descendants widgets."""
1771 for c in self.children.values(): c.destroy()
1772 if self.master.children.has_key(self._name):
1773 del self.master.children[self._name]
1774 self.tk.call('destroy', self._w)
1775 Misc.destroy(self)
1776 def _do(self, name, args=()):
1777 # XXX Obsolete -- better use self.tk.call directly!
1778 return self.tk.call((self._w, name) + args)
Guido van Rossum18468821994-06-20 07:49:28 +00001779
Guido van Rossum368e06b1997-11-07 20:38:49 +00001780class Widget(BaseWidget, Pack, Place, Grid):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001781 """Internal class.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001782
Fredrik Lundh06d28152000-08-09 18:03:12 +00001783 Base class for a widget which can be positioned with the geometry managers
1784 Pack, Place or Grid."""
1785 pass
Guido van Rossum368e06b1997-11-07 20:38:49 +00001786
1787class Toplevel(BaseWidget, Wm):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001788 """Toplevel widget, e.g. for dialogs."""
1789 def __init__(self, master=None, cnf={}, **kw):
1790 """Construct a toplevel widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001791
Fredrik Lundh06d28152000-08-09 18:03:12 +00001792 Valid resource names: background, bd, bg, borderwidth, class,
1793 colormap, container, cursor, height, highlightbackground,
1794 highlightcolor, highlightthickness, menu, relief, screen, takefocus,
1795 use, visual, width."""
1796 if kw:
1797 cnf = _cnfmerge((cnf, kw))
1798 extra = ()
1799 for wmkey in ['screen', 'class_', 'class', 'visual',
1800 'colormap']:
1801 if cnf.has_key(wmkey):
1802 val = cnf[wmkey]
1803 # TBD: a hack needed because some keys
1804 # are not valid as keyword arguments
1805 if wmkey[-1] == '_': opt = '-'+wmkey[:-1]
1806 else: opt = '-'+wmkey
1807 extra = extra + (opt, val)
1808 del cnf[wmkey]
1809 BaseWidget.__init__(self, master, 'toplevel', cnf, {}, extra)
1810 root = self._root()
1811 self.iconname(root.iconname())
1812 self.title(root.title())
1813 self.protocol("WM_DELETE_WINDOW", self.destroy)
Guido van Rossum18468821994-06-20 07:49:28 +00001814
1815class Button(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001816 """Button widget."""
1817 def __init__(self, master=None, cnf={}, **kw):
1818 """Construct a button widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001819
Fredrik Lundh06d28152000-08-09 18:03:12 +00001820 Valid resource names: activebackground, activeforeground, anchor,
1821 background, bd, bg, bitmap, borderwidth, command, cursor, default,
1822 disabledforeground, fg, font, foreground, height,
1823 highlightbackground, highlightcolor, highlightthickness, image,
1824 justify, padx, pady, relief, state, takefocus, text, textvariable,
1825 underline, width, wraplength."""
1826 Widget.__init__(self, master, 'button', cnf, kw)
1827 def tkButtonEnter(self, *dummy):
1828 self.tk.call('tkButtonEnter', self._w)
1829 def tkButtonLeave(self, *dummy):
1830 self.tk.call('tkButtonLeave', self._w)
1831 def tkButtonDown(self, *dummy):
1832 self.tk.call('tkButtonDown', self._w)
1833 def tkButtonUp(self, *dummy):
1834 self.tk.call('tkButtonUp', self._w)
1835 def tkButtonInvoke(self, *dummy):
1836 self.tk.call('tkButtonInvoke', self._w)
1837 def flash(self):
1838 self.tk.call(self._w, 'flash')
1839 def invoke(self):
1840 return self.tk.call(self._w, 'invoke')
Guido van Rossum18468821994-06-20 07:49:28 +00001841
1842# Indices:
Guido van Rossum35f67fb1995-08-04 03:50:29 +00001843# XXX I don't like these -- take them away
Guido van Rossum18468821994-06-20 07:49:28 +00001844def AtEnd():
Fredrik Lundh06d28152000-08-09 18:03:12 +00001845 return 'end'
Guido van Rossum1e9e4001994-06-20 09:09:51 +00001846def AtInsert(*args):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001847 s = 'insert'
1848 for a in args:
1849 if a: s = s + (' ' + a)
1850 return s
Guido van Rossum18468821994-06-20 07:49:28 +00001851def AtSelFirst():
Fredrik Lundh06d28152000-08-09 18:03:12 +00001852 return 'sel.first'
Guido van Rossum18468821994-06-20 07:49:28 +00001853def AtSelLast():
Fredrik Lundh06d28152000-08-09 18:03:12 +00001854 return 'sel.last'
Guido van Rossum18468821994-06-20 07:49:28 +00001855def At(x, y=None):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001856 if y is None:
1857 return '@' + `x`
1858 else:
1859 return '@' + `x` + ',' + `y`
Guido van Rossum18468821994-06-20 07:49:28 +00001860
1861class Canvas(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001862 """Canvas widget to display graphical elements like lines or text."""
1863 def __init__(self, master=None, cnf={}, **kw):
1864 """Construct a canvas widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001865
Fredrik Lundh06d28152000-08-09 18:03:12 +00001866 Valid resource names: background, bd, bg, borderwidth, closeenough,
1867 confine, cursor, height, highlightbackground, highlightcolor,
1868 highlightthickness, insertbackground, insertborderwidth,
1869 insertofftime, insertontime, insertwidth, offset, relief,
1870 scrollregion, selectbackground, selectborderwidth, selectforeground,
1871 state, takefocus, width, xscrollcommand, xscrollincrement,
1872 yscrollcommand, yscrollincrement."""
1873 Widget.__init__(self, master, 'canvas', cnf, kw)
1874 def addtag(self, *args):
1875 """Internal function."""
1876 self.tk.call((self._w, 'addtag') + args)
1877 def addtag_above(self, newtag, tagOrId):
1878 """Add tag NEWTAG to all items above TAGORID."""
1879 self.addtag(newtag, 'above', tagOrId)
1880 def addtag_all(self, newtag):
1881 """Add tag NEWTAG to all items."""
1882 self.addtag(newtag, 'all')
1883 def addtag_below(self, newtag, tagOrId):
1884 """Add tag NEWTAG to all items below TAGORID."""
1885 self.addtag(newtag, 'below', tagOrId)
1886 def addtag_closest(self, newtag, x, y, halo=None, start=None):
1887 """Add tag NEWTAG to item which is closest to pixel at X, Y.
1888 If several match take the top-most.
1889 All items closer than HALO are considered overlapping (all are
1890 closests). If START is specified the next below this tag is taken."""
1891 self.addtag(newtag, 'closest', x, y, halo, start)
1892 def addtag_enclosed(self, newtag, x1, y1, x2, y2):
1893 """Add tag NEWTAG to all items in the rectangle defined
1894 by X1,Y1,X2,Y2."""
1895 self.addtag(newtag, 'enclosed', x1, y1, x2, y2)
1896 def addtag_overlapping(self, newtag, x1, y1, x2, y2):
1897 """Add tag NEWTAG to all items which overlap the rectangle
1898 defined by X1,Y1,X2,Y2."""
1899 self.addtag(newtag, 'overlapping', x1, y1, x2, y2)
1900 def addtag_withtag(self, newtag, tagOrId):
1901 """Add tag NEWTAG to all items with TAGORID."""
1902 self.addtag(newtag, 'withtag', tagOrId)
1903 def bbox(self, *args):
1904 """Return a tuple of X1,Y1,X2,Y2 coordinates for a rectangle
1905 which encloses all items with tags specified as arguments."""
1906 return self._getints(
1907 self.tk.call((self._w, 'bbox') + args)) or None
1908 def tag_unbind(self, tagOrId, sequence, funcid=None):
1909 """Unbind for all items with TAGORID for event SEQUENCE the
1910 function identified with FUNCID."""
1911 self.tk.call(self._w, 'bind', tagOrId, sequence, '')
1912 if funcid:
1913 self.deletecommand(funcid)
1914 def tag_bind(self, tagOrId, sequence=None, func=None, add=None):
1915 """Bind to all items with TAGORID at event SEQUENCE a call to function FUNC.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001916
Fredrik Lundh06d28152000-08-09 18:03:12 +00001917 An additional boolean parameter ADD specifies whether FUNC will be
1918 called additionally to the other bound function or whether it will
1919 replace the previous function. See bind for the return value."""
1920 return self._bind((self._w, 'bind', tagOrId),
1921 sequence, func, add)
1922 def canvasx(self, screenx, gridspacing=None):
1923 """Return the canvas x coordinate of pixel position SCREENX rounded
1924 to nearest multiple of GRIDSPACING units."""
1925 return getdouble(self.tk.call(
1926 self._w, 'canvasx', screenx, gridspacing))
1927 def canvasy(self, screeny, gridspacing=None):
1928 """Return the canvas y coordinate of pixel position SCREENY rounded
1929 to nearest multiple of GRIDSPACING units."""
1930 return getdouble(self.tk.call(
1931 self._w, 'canvasy', screeny, gridspacing))
1932 def coords(self, *args):
1933 """Return a list of coordinates for the item given in ARGS."""
1934 # XXX Should use _flatten on args
1935 return map(getdouble,
Guido van Rossum0bd54331998-05-19 21:18:13 +00001936 self.tk.splitlist(
Fredrik Lundh06d28152000-08-09 18:03:12 +00001937 self.tk.call((self._w, 'coords') + args)))
1938 def _create(self, itemType, args, kw): # Args: (val, val, ..., cnf={})
1939 """Internal function."""
1940 args = _flatten(args)
1941 cnf = args[-1]
1942 if type(cnf) in (DictionaryType, TupleType):
1943 args = args[:-1]
1944 else:
1945 cnf = {}
1946 return getint(apply(
1947 self.tk.call,
1948 (self._w, 'create', itemType)
1949 + args + self._options(cnf, kw)))
1950 def create_arc(self, *args, **kw):
1951 """Create arc shaped region with coordinates x1,y1,x2,y2."""
1952 return self._create('arc', args, kw)
1953 def create_bitmap(self, *args, **kw):
1954 """Create bitmap with coordinates x1,y1."""
1955 return self._create('bitmap', args, kw)
1956 def create_image(self, *args, **kw):
1957 """Create image item with coordinates x1,y1."""
1958 return self._create('image', args, kw)
1959 def create_line(self, *args, **kw):
1960 """Create line with coordinates x1,y1,...,xn,yn."""
1961 return self._create('line', args, kw)
1962 def create_oval(self, *args, **kw):
1963 """Create oval with coordinates x1,y1,x2,y2."""
1964 return self._create('oval', args, kw)
1965 def create_polygon(self, *args, **kw):
1966 """Create polygon with coordinates x1,y1,...,xn,yn."""
1967 return self._create('polygon', args, kw)
1968 def create_rectangle(self, *args, **kw):
1969 """Create rectangle with coordinates x1,y1,x2,y2."""
1970 return self._create('rectangle', args, kw)
1971 def create_text(self, *args, **kw):
1972 """Create text with coordinates x1,y1."""
1973 return self._create('text', args, kw)
1974 def create_window(self, *args, **kw):
1975 """Create window with coordinates x1,y1,x2,y2."""
1976 return self._create('window', args, kw)
1977 def dchars(self, *args):
1978 """Delete characters of text items identified by tag or id in ARGS (possibly
1979 several times) from FIRST to LAST character (including)."""
1980 self.tk.call((self._w, 'dchars') + args)
1981 def delete(self, *args):
1982 """Delete items identified by all tag or ids contained in ARGS."""
1983 self.tk.call((self._w, 'delete') + args)
1984 def dtag(self, *args):
1985 """Delete tag or id given as last arguments in ARGS from items
1986 identified by first argument in ARGS."""
1987 self.tk.call((self._w, 'dtag') + args)
1988 def find(self, *args):
1989 """Internal function."""
1990 return self._getints(
1991 self.tk.call((self._w, 'find') + args)) or ()
1992 def find_above(self, tagOrId):
1993 """Return items above TAGORID."""
1994 return self.find('above', tagOrId)
1995 def find_all(self):
1996 """Return all items."""
1997 return self.find('all')
1998 def find_below(self, tagOrId):
1999 """Return all items below TAGORID."""
2000 return self.find('below', tagOrId)
2001 def find_closest(self, x, y, halo=None, start=None):
2002 """Return item which is closest to pixel at X, Y.
2003 If several match take the top-most.
2004 All items closer than HALO are considered overlapping (all are
2005 closests). If START is specified the next below this tag is taken."""
2006 return self.find('closest', x, y, halo, start)
2007 def find_enclosed(self, x1, y1, x2, y2):
2008 """Return all items in rectangle defined
2009 by X1,Y1,X2,Y2."""
2010 return self.find('enclosed', x1, y1, x2, y2)
2011 def find_overlapping(self, x1, y1, x2, y2):
2012 """Return all items which overlap the rectangle
2013 defined by X1,Y1,X2,Y2."""
2014 return self.find('overlapping', x1, y1, x2, y2)
2015 def find_withtag(self, tagOrId):
2016 """Return all items with TAGORID."""
2017 return self.find('withtag', tagOrId)
2018 def focus(self, *args):
2019 """Set focus to the first item specified in ARGS."""
2020 return self.tk.call((self._w, 'focus') + args)
2021 def gettags(self, *args):
2022 """Return tags associated with the first item specified in ARGS."""
2023 return self.tk.splitlist(
2024 self.tk.call((self._w, 'gettags') + args))
2025 def icursor(self, *args):
2026 """Set cursor at position POS in the item identified by TAGORID.
2027 In ARGS TAGORID must be first."""
2028 self.tk.call((self._w, 'icursor') + args)
2029 def index(self, *args):
2030 """Return position of cursor as integer in item specified in ARGS."""
2031 return getint(self.tk.call((self._w, 'index') + args))
2032 def insert(self, *args):
2033 """Insert TEXT in item TAGORID at position POS. ARGS must
2034 be TAGORID POS TEXT."""
2035 self.tk.call((self._w, 'insert') + args)
2036 def itemcget(self, tagOrId, option):
2037 """Return the resource value for an OPTION for item TAGORID."""
2038 return self.tk.call(
2039 (self._w, 'itemcget') + (tagOrId, '-'+option))
2040 def itemconfigure(self, tagOrId, cnf=None, **kw):
2041 """Configure resources of an item TAGORID.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002042
Fredrik Lundh06d28152000-08-09 18:03:12 +00002043 The values for resources are specified as keyword
2044 arguments. To get an overview about
2045 the allowed keyword arguments call the method without arguments.
2046 """
Martin v. Löwis6ce13152002-10-10 14:36:13 +00002047 return self._configure(('itemconfigure', tagOrId), cnf, kw)
Fredrik Lundh06d28152000-08-09 18:03:12 +00002048 itemconfig = itemconfigure
2049 # lower, tkraise/lift hide Misc.lower, Misc.tkraise/lift,
2050 # so the preferred name for them is tag_lower, tag_raise
2051 # (similar to tag_bind, and similar to the Text widget);
2052 # unfortunately can't delete the old ones yet (maybe in 1.6)
2053 def tag_lower(self, *args):
2054 """Lower an item TAGORID given in ARGS
2055 (optional below another item)."""
2056 self.tk.call((self._w, 'lower') + args)
2057 lower = tag_lower
2058 def move(self, *args):
2059 """Move an item TAGORID given in ARGS."""
2060 self.tk.call((self._w, 'move') + args)
2061 def postscript(self, cnf={}, **kw):
2062 """Print the contents of the canvas to a postscript
2063 file. Valid options: colormap, colormode, file, fontmap,
2064 height, pageanchor, pageheight, pagewidth, pagex, pagey,
2065 rotate, witdh, x, y."""
2066 return self.tk.call((self._w, 'postscript') +
2067 self._options(cnf, kw))
2068 def tag_raise(self, *args):
2069 """Raise an item TAGORID given in ARGS
2070 (optional above another item)."""
2071 self.tk.call((self._w, 'raise') + args)
2072 lift = tkraise = tag_raise
2073 def scale(self, *args):
2074 """Scale item TAGORID with XORIGIN, YORIGIN, XSCALE, YSCALE."""
2075 self.tk.call((self._w, 'scale') + args)
2076 def scan_mark(self, x, y):
2077 """Remember the current X, Y coordinates."""
2078 self.tk.call(self._w, 'scan', 'mark', x, y)
2079 def scan_dragto(self, x, y):
2080 """Adjust the view of the canvas to 10 times the
2081 difference between X and Y and the coordinates given in
2082 scan_mark."""
2083 self.tk.call(self._w, 'scan', 'dragto', x, y)
2084 def select_adjust(self, tagOrId, index):
2085 """Adjust the end of the selection near the cursor of an item TAGORID to index."""
2086 self.tk.call(self._w, 'select', 'adjust', tagOrId, index)
2087 def select_clear(self):
2088 """Clear the selection if it is in this widget."""
2089 self.tk.call(self._w, 'select', 'clear')
2090 def select_from(self, tagOrId, index):
2091 """Set the fixed end of a selection in item TAGORID to INDEX."""
2092 self.tk.call(self._w, 'select', 'from', tagOrId, index)
2093 def select_item(self):
2094 """Return the item which has the selection."""
Neal Norwitz58b63bf2002-07-23 02:52:58 +00002095 return self.tk.call(self._w, 'select', 'item') or None
Fredrik Lundh06d28152000-08-09 18:03:12 +00002096 def select_to(self, tagOrId, index):
2097 """Set the variable end of a selection in item TAGORID to INDEX."""
2098 self.tk.call(self._w, 'select', 'to', tagOrId, index)
2099 def type(self, tagOrId):
2100 """Return the type of the item TAGORID."""
2101 return self.tk.call(self._w, 'type', tagOrId) or None
2102 def xview(self, *args):
2103 """Query and change horizontal position of the view."""
2104 if not args:
2105 return self._getdoubles(self.tk.call(self._w, 'xview'))
2106 self.tk.call((self._w, 'xview') + args)
2107 def xview_moveto(self, fraction):
2108 """Adjusts the view in the window so that FRACTION of the
2109 total width of the canvas is off-screen to the left."""
2110 self.tk.call(self._w, 'xview', 'moveto', fraction)
2111 def xview_scroll(self, number, what):
2112 """Shift the x-view according to NUMBER which is measured in "units" or "pages" (WHAT)."""
2113 self.tk.call(self._w, 'xview', 'scroll', number, what)
2114 def yview(self, *args):
2115 """Query and change vertical position of the view."""
2116 if not args:
2117 return self._getdoubles(self.tk.call(self._w, 'yview'))
2118 self.tk.call((self._w, 'yview') + args)
2119 def yview_moveto(self, fraction):
2120 """Adjusts the view in the window so that FRACTION of the
2121 total height of the canvas is off-screen to the top."""
2122 self.tk.call(self._w, 'yview', 'moveto', fraction)
2123 def yview_scroll(self, number, what):
2124 """Shift the y-view according to NUMBER which is measured in "units" or "pages" (WHAT)."""
2125 self.tk.call(self._w, 'yview', 'scroll', number, what)
Guido van Rossum18468821994-06-20 07:49:28 +00002126
2127class Checkbutton(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002128 """Checkbutton widget which is either in on- or off-state."""
2129 def __init__(self, master=None, cnf={}, **kw):
2130 """Construct a checkbutton widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002131
Fredrik Lundh06d28152000-08-09 18:03:12 +00002132 Valid resource names: activebackground, activeforeground, anchor,
2133 background, bd, bg, bitmap, borderwidth, command, cursor,
2134 disabledforeground, fg, font, foreground, height,
2135 highlightbackground, highlightcolor, highlightthickness, image,
2136 indicatoron, justify, offvalue, onvalue, padx, pady, relief,
2137 selectcolor, selectimage, state, takefocus, text, textvariable,
2138 underline, variable, width, wraplength."""
2139 Widget.__init__(self, master, 'checkbutton', cnf, kw)
2140 def deselect(self):
2141 """Put the button in off-state."""
2142 self.tk.call(self._w, 'deselect')
2143 def flash(self):
2144 """Flash the button."""
2145 self.tk.call(self._w, 'flash')
2146 def invoke(self):
2147 """Toggle the button and invoke a command if given as resource."""
2148 return self.tk.call(self._w, 'invoke')
2149 def select(self):
2150 """Put the button in on-state."""
2151 self.tk.call(self._w, 'select')
2152 def toggle(self):
2153 """Toggle the button."""
2154 self.tk.call(self._w, 'toggle')
Guido van Rossum18468821994-06-20 07:49:28 +00002155
2156class Entry(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002157 """Entry widget which allows to display simple text."""
2158 def __init__(self, master=None, cnf={}, **kw):
2159 """Construct an entry widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002160
Fredrik Lundh06d28152000-08-09 18:03:12 +00002161 Valid resource names: background, bd, bg, borderwidth, cursor,
2162 exportselection, fg, font, foreground, highlightbackground,
2163 highlightcolor, highlightthickness, insertbackground,
2164 insertborderwidth, insertofftime, insertontime, insertwidth,
2165 invalidcommand, invcmd, justify, relief, selectbackground,
2166 selectborderwidth, selectforeground, show, state, takefocus,
2167 textvariable, validate, validatecommand, vcmd, width,
2168 xscrollcommand."""
2169 Widget.__init__(self, master, 'entry', cnf, kw)
2170 def delete(self, first, last=None):
2171 """Delete text from FIRST to LAST (not included)."""
2172 self.tk.call(self._w, 'delete', first, last)
2173 def get(self):
2174 """Return the text."""
2175 return self.tk.call(self._w, 'get')
2176 def icursor(self, index):
2177 """Insert cursor at INDEX."""
2178 self.tk.call(self._w, 'icursor', index)
2179 def index(self, index):
2180 """Return position of cursor."""
2181 return getint(self.tk.call(
2182 self._w, 'index', index))
2183 def insert(self, index, string):
2184 """Insert STRING at INDEX."""
2185 self.tk.call(self._w, 'insert', index, string)
2186 def scan_mark(self, x):
2187 """Remember the current X, Y coordinates."""
2188 self.tk.call(self._w, 'scan', 'mark', x)
2189 def scan_dragto(self, x):
2190 """Adjust the view of the canvas to 10 times the
2191 difference between X and Y and the coordinates given in
2192 scan_mark."""
2193 self.tk.call(self._w, 'scan', 'dragto', x)
2194 def selection_adjust(self, index):
2195 """Adjust the end of the selection near the cursor to INDEX."""
2196 self.tk.call(self._w, 'selection', 'adjust', index)
2197 select_adjust = selection_adjust
2198 def selection_clear(self):
2199 """Clear the selection if it is in this widget."""
2200 self.tk.call(self._w, 'selection', 'clear')
2201 select_clear = selection_clear
2202 def selection_from(self, index):
2203 """Set the fixed end of a selection to INDEX."""
2204 self.tk.call(self._w, 'selection', 'from', index)
2205 select_from = selection_from
2206 def selection_present(self):
2207 """Return whether the widget has the selection."""
2208 return self.tk.getboolean(
2209 self.tk.call(self._w, 'selection', 'present'))
2210 select_present = selection_present
2211 def selection_range(self, start, end):
2212 """Set the selection from START to END (not included)."""
2213 self.tk.call(self._w, 'selection', 'range', start, end)
2214 select_range = selection_range
2215 def selection_to(self, index):
2216 """Set the variable end of a selection to INDEX."""
2217 self.tk.call(self._w, 'selection', 'to', index)
2218 select_to = selection_to
2219 def xview(self, index):
2220 """Query and change horizontal position of the view."""
2221 self.tk.call(self._w, 'xview', index)
2222 def xview_moveto(self, fraction):
2223 """Adjust the view in the window so that FRACTION of the
2224 total width of the entry is off-screen to the left."""
2225 self.tk.call(self._w, 'xview', 'moveto', fraction)
2226 def xview_scroll(self, number, what):
2227 """Shift the x-view according to NUMBER which is measured in "units" or "pages" (WHAT)."""
2228 self.tk.call(self._w, 'xview', 'scroll', number, what)
Guido van Rossum18468821994-06-20 07:49:28 +00002229
2230class Frame(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002231 """Frame widget which may contain other widgets and can have a 3D border."""
2232 def __init__(self, master=None, cnf={}, **kw):
2233 """Construct a frame widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002234
Fredrik Lundh06d28152000-08-09 18:03:12 +00002235 Valid resource names: background, bd, bg, borderwidth, class,
2236 colormap, container, cursor, height, highlightbackground,
2237 highlightcolor, highlightthickness, relief, takefocus, visual, width."""
2238 cnf = _cnfmerge((cnf, kw))
2239 extra = ()
2240 if cnf.has_key('class_'):
2241 extra = ('-class', cnf['class_'])
2242 del cnf['class_']
2243 elif cnf.has_key('class'):
2244 extra = ('-class', cnf['class'])
2245 del cnf['class']
2246 Widget.__init__(self, master, 'frame', cnf, {}, extra)
Guido van Rossum18468821994-06-20 07:49:28 +00002247
2248class Label(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002249 """Label widget which can display text and bitmaps."""
2250 def __init__(self, master=None, cnf={}, **kw):
2251 """Construct a label widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002252
Fredrik Lundh06d28152000-08-09 18:03:12 +00002253 Valid resource names: anchor, background, bd, bg, bitmap,
2254 borderwidth, cursor, fg, font, foreground, height,
2255 highlightbackground, highlightcolor, highlightthickness, image,
2256 justify, padx, pady, relief, takefocus, text, textvariable,
2257 underline, width, wraplength."""
2258 Widget.__init__(self, master, 'label', cnf, kw)
Guido van Rossum761c5ab1995-07-14 15:29:10 +00002259
Guido van Rossum18468821994-06-20 07:49:28 +00002260class Listbox(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002261 """Listbox widget which can display a list of strings."""
2262 def __init__(self, master=None, cnf={}, **kw):
2263 """Construct a listbox widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002264
Fredrik Lundh06d28152000-08-09 18:03:12 +00002265 Valid resource names: background, bd, bg, borderwidth, cursor,
2266 exportselection, fg, font, foreground, height, highlightbackground,
2267 highlightcolor, highlightthickness, relief, selectbackground,
2268 selectborderwidth, selectforeground, selectmode, setgrid, takefocus,
2269 width, xscrollcommand, yscrollcommand, listvariable."""
2270 Widget.__init__(self, master, 'listbox', cnf, kw)
2271 def activate(self, index):
2272 """Activate item identified by INDEX."""
2273 self.tk.call(self._w, 'activate', index)
2274 def bbox(self, *args):
2275 """Return a tuple of X1,Y1,X2,Y2 coordinates for a rectangle
2276 which encloses the item identified by index in ARGS."""
2277 return self._getints(
2278 self.tk.call((self._w, 'bbox') + args)) or None
2279 def curselection(self):
2280 """Return list of indices of currently selected item."""
2281 # XXX Ought to apply self._getints()...
2282 return self.tk.splitlist(self.tk.call(
2283 self._w, 'curselection'))
2284 def delete(self, first, last=None):
2285 """Delete items from FIRST to LAST (not included)."""
2286 self.tk.call(self._w, 'delete', first, last)
2287 def get(self, first, last=None):
2288 """Get list of items from FIRST to LAST (not included)."""
2289 if last:
2290 return self.tk.splitlist(self.tk.call(
2291 self._w, 'get', first, last))
2292 else:
2293 return self.tk.call(self._w, 'get', first)
2294 def index(self, index):
2295 """Return index of item identified with INDEX."""
2296 i = self.tk.call(self._w, 'index', index)
2297 if i == 'none': return None
2298 return getint(i)
2299 def insert(self, index, *elements):
2300 """Insert ELEMENTS at INDEX."""
2301 self.tk.call((self._w, 'insert', index) + elements)
2302 def nearest(self, y):
2303 """Get index of item which is nearest to y coordinate Y."""
2304 return getint(self.tk.call(
2305 self._w, 'nearest', y))
2306 def scan_mark(self, x, y):
2307 """Remember the current X, Y coordinates."""
2308 self.tk.call(self._w, 'scan', 'mark', x, y)
2309 def scan_dragto(self, x, y):
2310 """Adjust the view of the listbox to 10 times the
2311 difference between X and Y and the coordinates given in
2312 scan_mark."""
2313 self.tk.call(self._w, 'scan', 'dragto', x, y)
2314 def see(self, index):
2315 """Scroll such that INDEX is visible."""
2316 self.tk.call(self._w, 'see', index)
2317 def selection_anchor(self, index):
2318 """Set the fixed end oft the selection to INDEX."""
2319 self.tk.call(self._w, 'selection', 'anchor', index)
2320 select_anchor = selection_anchor
2321 def selection_clear(self, first, last=None):
2322 """Clear the selection from FIRST to LAST (not included)."""
2323 self.tk.call(self._w,
2324 'selection', 'clear', first, last)
2325 select_clear = selection_clear
2326 def selection_includes(self, index):
2327 """Return 1 if INDEX is part of the selection."""
2328 return self.tk.getboolean(self.tk.call(
2329 self._w, 'selection', 'includes', index))
2330 select_includes = selection_includes
2331 def selection_set(self, first, last=None):
2332 """Set the selection from FIRST to LAST (not included) without
2333 changing the currently selected elements."""
2334 self.tk.call(self._w, 'selection', 'set', first, last)
2335 select_set = selection_set
2336 def size(self):
2337 """Return the number of elements in the listbox."""
2338 return getint(self.tk.call(self._w, 'size'))
2339 def xview(self, *what):
2340 """Query and change horizontal position of the view."""
2341 if not what:
2342 return self._getdoubles(self.tk.call(self._w, 'xview'))
2343 self.tk.call((self._w, 'xview') + what)
2344 def xview_moveto(self, fraction):
2345 """Adjust the view in the window so that FRACTION of the
2346 total width of the entry is off-screen to the left."""
2347 self.tk.call(self._w, 'xview', 'moveto', fraction)
2348 def xview_scroll(self, number, what):
2349 """Shift the x-view according to NUMBER which is measured in "units" or "pages" (WHAT)."""
2350 self.tk.call(self._w, 'xview', 'scroll', number, what)
2351 def yview(self, *what):
2352 """Query and change vertical position of the view."""
2353 if not what:
2354 return self._getdoubles(self.tk.call(self._w, 'yview'))
2355 self.tk.call((self._w, 'yview') + what)
2356 def yview_moveto(self, fraction):
2357 """Adjust the view in the window so that FRACTION of the
2358 total width of the entry is off-screen to the top."""
2359 self.tk.call(self._w, 'yview', 'moveto', fraction)
2360 def yview_scroll(self, number, what):
2361 """Shift the y-view according to NUMBER which is measured in "units" or "pages" (WHAT)."""
2362 self.tk.call(self._w, 'yview', 'scroll', number, what)
Guido van Rossum09f1ad82001-09-05 19:29:56 +00002363 def itemcget(self, index, option):
2364 """Return the resource value for an ITEM and an OPTION."""
2365 return self.tk.call(
2366 (self._w, 'itemcget') + (index, '-'+option))
Guido van Rossuma0adb922001-09-01 18:29:55 +00002367 def itemconfigure(self, index, cnf=None, **kw):
Guido van Rossum09f1ad82001-09-05 19:29:56 +00002368 """Configure resources of an ITEM.
Guido van Rossuma0adb922001-09-01 18:29:55 +00002369
2370 The values for resources are specified as keyword arguments.
2371 To get an overview about the allowed keyword arguments
2372 call the method without arguments.
2373 Valid resource names: background, bg, foreground, fg,
2374 selectbackground, selectforeground."""
Martin v. Löwis6ce13152002-10-10 14:36:13 +00002375 return self._configure(('itemconfigure', index), cnf, kw)
Guido van Rossuma0adb922001-09-01 18:29:55 +00002376 itemconfig = itemconfigure
Guido van Rossum18468821994-06-20 07:49:28 +00002377
2378class Menu(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002379 """Menu widget which allows to display menu bars, pull-down menus and pop-up menus."""
2380 def __init__(self, master=None, cnf={}, **kw):
2381 """Construct menu widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002382
Fredrik Lundh06d28152000-08-09 18:03:12 +00002383 Valid resource names: activebackground, activeborderwidth,
2384 activeforeground, background, bd, bg, borderwidth, cursor,
2385 disabledforeground, fg, font, foreground, postcommand, relief,
2386 selectcolor, takefocus, tearoff, tearoffcommand, title, type."""
2387 Widget.__init__(self, master, 'menu', cnf, kw)
2388 def tk_bindForTraversal(self):
2389 pass # obsolete since Tk 4.0
2390 def tk_mbPost(self):
2391 self.tk.call('tk_mbPost', self._w)
2392 def tk_mbUnpost(self):
2393 self.tk.call('tk_mbUnpost')
2394 def tk_traverseToMenu(self, char):
2395 self.tk.call('tk_traverseToMenu', self._w, char)
2396 def tk_traverseWithinMenu(self, char):
2397 self.tk.call('tk_traverseWithinMenu', self._w, char)
2398 def tk_getMenuButtons(self):
2399 return self.tk.call('tk_getMenuButtons', self._w)
2400 def tk_nextMenu(self, count):
2401 self.tk.call('tk_nextMenu', count)
2402 def tk_nextMenuEntry(self, count):
2403 self.tk.call('tk_nextMenuEntry', count)
2404 def tk_invokeMenu(self):
2405 self.tk.call('tk_invokeMenu', self._w)
2406 def tk_firstMenu(self):
2407 self.tk.call('tk_firstMenu', self._w)
2408 def tk_mbButtonDown(self):
2409 self.tk.call('tk_mbButtonDown', self._w)
2410 def tk_popup(self, x, y, entry=""):
2411 """Post the menu at position X,Y with entry ENTRY."""
2412 self.tk.call('tk_popup', self._w, x, y, entry)
2413 def activate(self, index):
2414 """Activate entry at INDEX."""
2415 self.tk.call(self._w, 'activate', index)
2416 def add(self, itemType, cnf={}, **kw):
2417 """Internal function."""
2418 self.tk.call((self._w, 'add', itemType) +
2419 self._options(cnf, kw))
2420 def add_cascade(self, cnf={}, **kw):
2421 """Add hierarchical menu item."""
2422 self.add('cascade', cnf or kw)
2423 def add_checkbutton(self, cnf={}, **kw):
2424 """Add checkbutton menu item."""
2425 self.add('checkbutton', cnf or kw)
2426 def add_command(self, cnf={}, **kw):
2427 """Add command menu item."""
2428 self.add('command', cnf or kw)
2429 def add_radiobutton(self, cnf={}, **kw):
2430 """Addd radio menu item."""
2431 self.add('radiobutton', cnf or kw)
2432 def add_separator(self, cnf={}, **kw):
2433 """Add separator."""
2434 self.add('separator', cnf or kw)
2435 def insert(self, index, itemType, cnf={}, **kw):
2436 """Internal function."""
2437 self.tk.call((self._w, 'insert', index, itemType) +
2438 self._options(cnf, kw))
2439 def insert_cascade(self, index, cnf={}, **kw):
2440 """Add hierarchical menu item at INDEX."""
2441 self.insert(index, 'cascade', cnf or kw)
2442 def insert_checkbutton(self, index, cnf={}, **kw):
2443 """Add checkbutton menu item at INDEX."""
2444 self.insert(index, 'checkbutton', cnf or kw)
2445 def insert_command(self, index, cnf={}, **kw):
2446 """Add command menu item at INDEX."""
2447 self.insert(index, 'command', cnf or kw)
2448 def insert_radiobutton(self, index, cnf={}, **kw):
2449 """Addd radio menu item at INDEX."""
2450 self.insert(index, 'radiobutton', cnf or kw)
2451 def insert_separator(self, index, cnf={}, **kw):
2452 """Add separator at INDEX."""
2453 self.insert(index, 'separator', cnf or kw)
2454 def delete(self, index1, index2=None):
2455 """Delete menu items between INDEX1 and INDEX2 (not included)."""
2456 self.tk.call(self._w, 'delete', index1, index2)
2457 def entrycget(self, index, option):
2458 """Return the resource value of an menu item for OPTION at INDEX."""
2459 return self.tk.call(self._w, 'entrycget', index, '-' + option)
2460 def entryconfigure(self, index, cnf=None, **kw):
2461 """Configure a menu item at INDEX."""
Martin v. Löwis6ce13152002-10-10 14:36:13 +00002462 return self._configure(('entryconfigure', index), cnf, kw)
Fredrik Lundh06d28152000-08-09 18:03:12 +00002463 entryconfig = entryconfigure
2464 def index(self, index):
2465 """Return the index of a menu item identified by INDEX."""
2466 i = self.tk.call(self._w, 'index', index)
2467 if i == 'none': return None
2468 return getint(i)
2469 def invoke(self, index):
2470 """Invoke a menu item identified by INDEX and execute
2471 the associated command."""
2472 return self.tk.call(self._w, 'invoke', index)
2473 def post(self, x, y):
2474 """Display a menu at position X,Y."""
2475 self.tk.call(self._w, 'post', x, y)
2476 def type(self, index):
2477 """Return the type of the menu item at INDEX."""
2478 return self.tk.call(self._w, 'type', index)
2479 def unpost(self):
2480 """Unmap a menu."""
2481 self.tk.call(self._w, 'unpost')
2482 def yposition(self, index):
2483 """Return the y-position of the topmost pixel of the menu item at INDEX."""
2484 return getint(self.tk.call(
2485 self._w, 'yposition', index))
Guido van Rossum18468821994-06-20 07:49:28 +00002486
2487class Menubutton(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002488 """Menubutton widget, obsolete since Tk8.0."""
2489 def __init__(self, master=None, cnf={}, **kw):
2490 Widget.__init__(self, master, 'menubutton', cnf, kw)
Guido van Rossum18468821994-06-20 07:49:28 +00002491
2492class Message(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002493 """Message widget to display multiline text. Obsolete since Label does it too."""
2494 def __init__(self, master=None, cnf={}, **kw):
2495 Widget.__init__(self, master, 'message', cnf, kw)
Guido van Rossum18468821994-06-20 07:49:28 +00002496
2497class Radiobutton(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002498 """Radiobutton widget which shows only one of several buttons in on-state."""
2499 def __init__(self, master=None, cnf={}, **kw):
2500 """Construct a radiobutton widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002501
Fredrik Lundh06d28152000-08-09 18:03:12 +00002502 Valid resource names: activebackground, activeforeground, anchor,
2503 background, bd, bg, bitmap, borderwidth, command, cursor,
2504 disabledforeground, fg, font, foreground, height,
2505 highlightbackground, highlightcolor, highlightthickness, image,
2506 indicatoron, justify, padx, pady, relief, selectcolor, selectimage,
2507 state, takefocus, text, textvariable, underline, value, variable,
2508 width, wraplength."""
2509 Widget.__init__(self, master, 'radiobutton', cnf, kw)
2510 def deselect(self):
2511 """Put the button in off-state."""
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002512
Fredrik Lundh06d28152000-08-09 18:03:12 +00002513 self.tk.call(self._w, 'deselect')
2514 def flash(self):
2515 """Flash the button."""
2516 self.tk.call(self._w, 'flash')
2517 def invoke(self):
2518 """Toggle the button and invoke a command if given as resource."""
2519 return self.tk.call(self._w, 'invoke')
2520 def select(self):
2521 """Put the button in on-state."""
2522 self.tk.call(self._w, 'select')
Guido van Rossum18468821994-06-20 07:49:28 +00002523
2524class Scale(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002525 """Scale widget which can display a numerical scale."""
2526 def __init__(self, master=None, cnf={}, **kw):
2527 """Construct a scale widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002528
Fredrik Lundh06d28152000-08-09 18:03:12 +00002529 Valid resource names: activebackground, background, bigincrement, bd,
2530 bg, borderwidth, command, cursor, digits, fg, font, foreground, from,
2531 highlightbackground, highlightcolor, highlightthickness, label,
2532 length, orient, relief, repeatdelay, repeatinterval, resolution,
2533 showvalue, sliderlength, sliderrelief, state, takefocus,
2534 tickinterval, to, troughcolor, variable, width."""
2535 Widget.__init__(self, master, 'scale', cnf, kw)
2536 def get(self):
2537 """Get the current value as integer or float."""
2538 value = self.tk.call(self._w, 'get')
2539 try:
2540 return getint(value)
2541 except ValueError:
2542 return getdouble(value)
2543 def set(self, value):
2544 """Set the value to VALUE."""
2545 self.tk.call(self._w, 'set', value)
2546 def coords(self, value=None):
2547 """Return a tuple (X,Y) of the point along the centerline of the
2548 trough that corresponds to VALUE or the current value if None is
2549 given."""
2550
2551 return self._getints(self.tk.call(self._w, 'coords', value))
2552 def identify(self, x, y):
2553 """Return where the point X,Y lies. Valid return values are "slider",
2554 "though1" and "though2"."""
2555 return self.tk.call(self._w, 'identify', x, y)
Guido van Rossum18468821994-06-20 07:49:28 +00002556
2557class Scrollbar(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002558 """Scrollbar widget which displays a slider at a certain position."""
2559 def __init__(self, master=None, cnf={}, **kw):
2560 """Construct a scrollbar 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, activerelief,
2563 background, bd, bg, borderwidth, command, cursor,
2564 elementborderwidth, highlightbackground,
2565 highlightcolor, highlightthickness, jump, orient,
2566 relief, repeatdelay, repeatinterval, takefocus,
2567 troughcolor, width."""
2568 Widget.__init__(self, master, 'scrollbar', cnf, kw)
2569 def activate(self, index):
2570 """Display the element at INDEX with activebackground and activerelief.
2571 INDEX can be "arrow1","slider" or "arrow2"."""
2572 self.tk.call(self._w, 'activate', index)
2573 def delta(self, deltax, deltay):
2574 """Return the fractional change of the scrollbar setting if it
2575 would be moved by DELTAX or DELTAY pixels."""
2576 return getdouble(
2577 self.tk.call(self._w, 'delta', deltax, deltay))
2578 def fraction(self, x, y):
2579 """Return the fractional value which corresponds to a slider
2580 position of X,Y."""
2581 return getdouble(self.tk.call(self._w, 'fraction', x, y))
2582 def identify(self, x, y):
2583 """Return the element under position X,Y as one of
2584 "arrow1","slider","arrow2" or ""."""
2585 return self.tk.call(self._w, 'identify', x, y)
2586 def get(self):
2587 """Return the current fractional values (upper and lower end)
2588 of the slider position."""
2589 return self._getdoubles(self.tk.call(self._w, 'get'))
2590 def set(self, *args):
2591 """Set the fractional values of the slider position (upper and
2592 lower ends as value between 0 and 1)."""
2593 self.tk.call((self._w, 'set') + args)
Guido van Rossum18468821994-06-20 07:49:28 +00002594
2595class Text(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002596 """Text widget which can display text in various forms."""
Fredrik Lundh06d28152000-08-09 18:03:12 +00002597 def __init__(self, master=None, cnf={}, **kw):
2598 """Construct a text widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002599
Fredrik Lundh06d28152000-08-09 18:03:12 +00002600 Valid resource names: background, bd, bg, borderwidth, cursor,
2601 exportselection, fg, font, foreground, height,
2602 highlightbackground, highlightcolor, highlightthickness,
2603 insertbackground, insertborderwidth, insertofftime,
2604 insertontime, insertwidth, padx, pady, relief,
2605 selectbackground, selectborderwidth, selectforeground,
2606 setgrid, spacing1, spacing2, spacing3, state, tabs, takefocus,
2607 width, wrap, xscrollcommand, yscrollcommand."""
2608 Widget.__init__(self, master, 'text', cnf, kw)
2609 def bbox(self, *args):
2610 """Return a tuple of (x,y,width,height) which gives the bounding
2611 box of the visible part of the character at the index in ARGS."""
2612 return self._getints(
2613 self.tk.call((self._w, 'bbox') + args)) or None
2614 def tk_textSelectTo(self, index):
2615 self.tk.call('tk_textSelectTo', self._w, index)
2616 def tk_textBackspace(self):
2617 self.tk.call('tk_textBackspace', self._w)
2618 def tk_textIndexCloser(self, a, b, c):
2619 self.tk.call('tk_textIndexCloser', self._w, a, b, c)
2620 def tk_textResetAnchor(self, index):
2621 self.tk.call('tk_textResetAnchor', self._w, index)
2622 def compare(self, index1, op, index2):
2623 """Return whether between index INDEX1 and index INDEX2 the
2624 relation OP is satisfied. OP is one of <, <=, ==, >=, >, or !=."""
2625 return self.tk.getboolean(self.tk.call(
2626 self._w, 'compare', index1, op, index2))
2627 def debug(self, boolean=None):
2628 """Turn on the internal consistency checks of the B-Tree inside the text
2629 widget according to BOOLEAN."""
2630 return self.tk.getboolean(self.tk.call(
2631 self._w, 'debug', boolean))
2632 def delete(self, index1, index2=None):
2633 """Delete the characters between INDEX1 and INDEX2 (not included)."""
2634 self.tk.call(self._w, 'delete', index1, index2)
2635 def dlineinfo(self, index):
2636 """Return tuple (x,y,width,height,baseline) giving the bounding box
2637 and baseline position of the visible part of the line containing
2638 the character at INDEX."""
2639 return self._getints(self.tk.call(self._w, 'dlineinfo', index))
Guido van Rossum256705b2002-04-23 13:29:43 +00002640 def dump(self, index1, index2=None, command=None, **kw):
2641 """Return the contents of the widget between index1 and index2.
2642
2643 The type of contents returned in filtered based on the keyword
2644 parameters; if 'all', 'image', 'mark', 'tag', 'text', or 'window' are
2645 given and true, then the corresponding items are returned. The result
2646 is a list of triples of the form (key, value, index). If none of the
2647 keywords are true then 'all' is used by default.
2648
2649 If the 'command' argument is given, it is called once for each element
2650 of the list of triples, with the values of each triple serving as the
2651 arguments to the function. In this case the list is not returned."""
2652 args = []
2653 func_name = None
2654 result = None
2655 if not command:
2656 # Never call the dump command without the -command flag, since the
2657 # output could involve Tcl quoting and would be a pain to parse
2658 # right. Instead just set the command to build a list of triples
2659 # as if we had done the parsing.
2660 result = []
2661 def append_triple(key, value, index, result=result):
2662 result.append((key, value, index))
2663 command = append_triple
2664 try:
2665 if not isinstance(command, str):
2666 func_name = command = self._register(command)
2667 args += ["-command", command]
2668 for key in kw:
2669 if kw[key]: args.append("-" + key)
2670 args.append(index1)
2671 if index2:
2672 args.append(index2)
2673 self.tk.call(self._w, "dump", *args)
2674 return result
2675 finally:
2676 if func_name:
2677 self.deletecommand(func_name)
Fredrik Lundh06d28152000-08-09 18:03:12 +00002678 def get(self, index1, index2=None):
2679 """Return the text from INDEX1 to INDEX2 (not included)."""
2680 return self.tk.call(self._w, 'get', index1, index2)
2681 # (Image commands are new in 8.0)
2682 def image_cget(self, index, option):
2683 """Return the value of OPTION of an embedded image at INDEX."""
2684 if option[:1] != "-":
2685 option = "-" + option
2686 if option[-1:] == "_":
2687 option = option[:-1]
2688 return self.tk.call(self._w, "image", "cget", index, option)
Martin v. Löwis6ce13152002-10-10 14:36:13 +00002689 def image_configure(self, index, cnf=None, **kw):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002690 """Configure an embedded image at INDEX."""
Martin v. Löwis6ce13152002-10-10 14:36:13 +00002691 return self._configure(('image', 'configure', index), cnf, kw)
Fredrik Lundh06d28152000-08-09 18:03:12 +00002692 def image_create(self, index, cnf={}, **kw):
2693 """Create an embedded image at INDEX."""
2694 return apply(self.tk.call,
2695 (self._w, "image", "create", index)
2696 + self._options(cnf, kw))
2697 def image_names(self):
2698 """Return all names of embedded images in this widget."""
2699 return self.tk.call(self._w, "image", "names")
2700 def index(self, index):
2701 """Return the index in the form line.char for INDEX."""
2702 return self.tk.call(self._w, 'index', index)
2703 def insert(self, index, chars, *args):
2704 """Insert CHARS before the characters at INDEX. An additional
2705 tag can be given in ARGS. Additional CHARS and tags can follow in ARGS."""
2706 self.tk.call((self._w, 'insert', index, chars) + args)
2707 def mark_gravity(self, markName, direction=None):
2708 """Change the gravity of a mark MARKNAME to DIRECTION (LEFT or RIGHT).
2709 Return the current value if None is given for DIRECTION."""
2710 return self.tk.call(
2711 (self._w, 'mark', 'gravity', markName, direction))
2712 def mark_names(self):
2713 """Return all mark names."""
2714 return self.tk.splitlist(self.tk.call(
2715 self._w, 'mark', 'names'))
2716 def mark_set(self, markName, index):
2717 """Set mark MARKNAME before the character at INDEX."""
2718 self.tk.call(self._w, 'mark', 'set', markName, index)
2719 def mark_unset(self, *markNames):
2720 """Delete all marks in MARKNAMES."""
2721 self.tk.call((self._w, 'mark', 'unset') + markNames)
2722 def mark_next(self, index):
2723 """Return the name of the next mark after INDEX."""
2724 return self.tk.call(self._w, 'mark', 'next', index) or None
2725 def mark_previous(self, index):
2726 """Return the name of the previous mark before INDEX."""
2727 return self.tk.call(self._w, 'mark', 'previous', index) or None
2728 def scan_mark(self, x, y):
2729 """Remember the current X, Y coordinates."""
2730 self.tk.call(self._w, 'scan', 'mark', x, y)
2731 def scan_dragto(self, x, y):
2732 """Adjust the view of the text to 10 times the
2733 difference between X and Y and the coordinates given in
2734 scan_mark."""
2735 self.tk.call(self._w, 'scan', 'dragto', x, y)
2736 def search(self, pattern, index, stopindex=None,
2737 forwards=None, backwards=None, exact=None,
2738 regexp=None, nocase=None, count=None):
2739 """Search PATTERN beginning from INDEX until STOPINDEX.
2740 Return the index of the first character of a match or an empty string."""
2741 args = [self._w, 'search']
2742 if forwards: args.append('-forwards')
2743 if backwards: args.append('-backwards')
2744 if exact: args.append('-exact')
2745 if regexp: args.append('-regexp')
2746 if nocase: args.append('-nocase')
2747 if count: args.append('-count'); args.append(count)
2748 if pattern[0] == '-': args.append('--')
2749 args.append(pattern)
2750 args.append(index)
2751 if stopindex: args.append(stopindex)
2752 return self.tk.call(tuple(args))
2753 def see(self, index):
2754 """Scroll such that the character at INDEX is visible."""
2755 self.tk.call(self._w, 'see', index)
2756 def tag_add(self, tagName, index1, *args):
2757 """Add tag TAGNAME to all characters between INDEX1 and index2 in ARGS.
2758 Additional pairs of indices may follow in ARGS."""
2759 self.tk.call(
2760 (self._w, 'tag', 'add', tagName, index1) + args)
2761 def tag_unbind(self, tagName, sequence, funcid=None):
2762 """Unbind for all characters with TAGNAME for event SEQUENCE the
2763 function identified with FUNCID."""
2764 self.tk.call(self._w, 'tag', 'bind', tagName, sequence, '')
2765 if funcid:
2766 self.deletecommand(funcid)
2767 def tag_bind(self, tagName, sequence, func, add=None):
2768 """Bind to all characters with TAGNAME at event SEQUENCE a call to function FUNC.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002769
Fredrik Lundh06d28152000-08-09 18:03:12 +00002770 An additional boolean parameter ADD specifies whether FUNC will be
2771 called additionally to the other bound function or whether it will
2772 replace the previous function. See bind for the return value."""
2773 return self._bind((self._w, 'tag', 'bind', tagName),
2774 sequence, func, add)
2775 def tag_cget(self, tagName, option):
2776 """Return the value of OPTION for tag TAGNAME."""
2777 if option[:1] != '-':
2778 option = '-' + option
2779 if option[-1:] == '_':
2780 option = option[:-1]
2781 return self.tk.call(self._w, 'tag', 'cget', tagName, option)
Martin v. Löwis6ce13152002-10-10 14:36:13 +00002782 def tag_configure(self, tagName, cnf=None, **kw):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002783 """Configure a tag TAGNAME."""
Martin v. Löwis6ce13152002-10-10 14:36:13 +00002784 return self._configure(('tag', 'configure', tagName), cnf, kw)
Fredrik Lundh06d28152000-08-09 18:03:12 +00002785 tag_config = tag_configure
2786 def tag_delete(self, *tagNames):
2787 """Delete all tags in TAGNAMES."""
2788 self.tk.call((self._w, 'tag', 'delete') + tagNames)
2789 def tag_lower(self, tagName, belowThis=None):
2790 """Change the priority of tag TAGNAME such that it is lower
2791 than the priority of BELOWTHIS."""
2792 self.tk.call(self._w, 'tag', 'lower', tagName, belowThis)
2793 def tag_names(self, index=None):
2794 """Return a list of all tag names."""
2795 return self.tk.splitlist(
2796 self.tk.call(self._w, 'tag', 'names', index))
2797 def tag_nextrange(self, tagName, index1, index2=None):
2798 """Return a list of start and end index for the first sequence of
2799 characters between INDEX1 and INDEX2 which all have tag TAGNAME.
2800 The text is searched forward from INDEX1."""
2801 return self.tk.splitlist(self.tk.call(
2802 self._w, 'tag', 'nextrange', tagName, index1, index2))
2803 def tag_prevrange(self, tagName, index1, index2=None):
2804 """Return a list of start and end index for the first sequence of
2805 characters between INDEX1 and INDEX2 which all have tag TAGNAME.
2806 The text is searched backwards from INDEX1."""
2807 return self.tk.splitlist(self.tk.call(
2808 self._w, 'tag', 'prevrange', tagName, index1, index2))
2809 def tag_raise(self, tagName, aboveThis=None):
2810 """Change the priority of tag TAGNAME such that it is higher
2811 than the priority of ABOVETHIS."""
2812 self.tk.call(
2813 self._w, 'tag', 'raise', tagName, aboveThis)
2814 def tag_ranges(self, tagName):
2815 """Return a list of ranges of text which have tag TAGNAME."""
2816 return self.tk.splitlist(self.tk.call(
2817 self._w, 'tag', 'ranges', tagName))
2818 def tag_remove(self, tagName, index1, index2=None):
2819 """Remove tag TAGNAME from all characters between INDEX1 and INDEX2."""
2820 self.tk.call(
2821 self._w, 'tag', 'remove', tagName, index1, index2)
2822 def window_cget(self, index, option):
2823 """Return the value of OPTION of an embedded window at INDEX."""
2824 if option[:1] != '-':
2825 option = '-' + option
2826 if option[-1:] == '_':
2827 option = option[:-1]
2828 return self.tk.call(self._w, 'window', 'cget', index, option)
Martin v. Löwis6ce13152002-10-10 14:36:13 +00002829 def window_configure(self, index, cnf=None, **kw):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002830 """Configure an embedded window at INDEX."""
Martin v. Löwis6ce13152002-10-10 14:36:13 +00002831 return self._configure(('window', 'configure', index), cnf, kw)
Fredrik Lundh06d28152000-08-09 18:03:12 +00002832 window_config = window_configure
2833 def window_create(self, index, cnf={}, **kw):
2834 """Create a window at INDEX."""
2835 self.tk.call(
2836 (self._w, 'window', 'create', index)
2837 + self._options(cnf, kw))
2838 def window_names(self):
2839 """Return all names of embedded windows in this widget."""
2840 return self.tk.splitlist(
2841 self.tk.call(self._w, 'window', 'names'))
2842 def xview(self, *what):
2843 """Query and change horizontal position of the view."""
2844 if not what:
2845 return self._getdoubles(self.tk.call(self._w, 'xview'))
2846 self.tk.call((self._w, 'xview') + what)
Fredrik Lundh5bd2cd62000-08-09 18:29:51 +00002847 def xview_moveto(self, fraction):
2848 """Adjusts the view in the window so that FRACTION of the
2849 total width of the canvas is off-screen to the left."""
2850 self.tk.call(self._w, 'xview', 'moveto', fraction)
2851 def xview_scroll(self, number, what):
2852 """Shift the x-view according to NUMBER which is measured
2853 in "units" or "pages" (WHAT)."""
2854 self.tk.call(self._w, 'xview', 'scroll', number, what)
Fredrik Lundh8fffa202000-08-09 18:51:01 +00002855 def yview(self, *what):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002856 """Query and change vertical position of the view."""
Fredrik Lundh8fffa202000-08-09 18:51:01 +00002857 if not what:
Fredrik Lundh06d28152000-08-09 18:03:12 +00002858 return self._getdoubles(self.tk.call(self._w, 'yview'))
Fredrik Lundh8fffa202000-08-09 18:51:01 +00002859 self.tk.call((self._w, 'yview') + what)
Fredrik Lundh5bd2cd62000-08-09 18:29:51 +00002860 def yview_moveto(self, fraction):
2861 """Adjusts the view in the window so that FRACTION of the
2862 total height of the canvas is off-screen to the top."""
2863 self.tk.call(self._w, 'yview', 'moveto', fraction)
2864 def yview_scroll(self, number, what):
2865 """Shift the y-view according to NUMBER which is measured
2866 in "units" or "pages" (WHAT)."""
2867 self.tk.call(self._w, 'yview', 'scroll', number, what)
Fredrik Lundh06d28152000-08-09 18:03:12 +00002868 def yview_pickplace(self, *what):
2869 """Obsolete function, use see."""
2870 self.tk.call((self._w, 'yview', '-pickplace') + what)
Guido van Rossum18468821994-06-20 07:49:28 +00002871
Guido van Rossum28574b51996-10-21 15:16:51 +00002872class _setit:
Fredrik Lundh06d28152000-08-09 18:03:12 +00002873 """Internal class. It wraps the command in the widget OptionMenu."""
2874 def __init__(self, var, value, callback=None):
2875 self.__value = value
2876 self.__var = var
2877 self.__callback = callback
2878 def __call__(self, *args):
2879 self.__var.set(self.__value)
2880 if self.__callback:
2881 apply(self.__callback, (self.__value,)+args)
Guido van Rossum28574b51996-10-21 15:16:51 +00002882
2883class OptionMenu(Menubutton):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002884 """OptionMenu which allows the user to select a value from a menu."""
2885 def __init__(self, master, variable, value, *values, **kwargs):
2886 """Construct an optionmenu widget with the parent MASTER, with
2887 the resource textvariable set to VARIABLE, the initially selected
2888 value VALUE, the other menu values VALUES and an additional
2889 keyword argument command."""
2890 kw = {"borderwidth": 2, "textvariable": variable,
2891 "indicatoron": 1, "relief": RAISED, "anchor": "c",
2892 "highlightthickness": 2}
2893 Widget.__init__(self, master, "menubutton", kw)
2894 self.widgetName = 'tk_optionMenu'
2895 menu = self.__menu = Menu(self, name="menu", tearoff=0)
2896 self.menuname = menu._w
2897 # 'command' is the only supported keyword
2898 callback = kwargs.get('command')
2899 if kwargs.has_key('command'):
2900 del kwargs['command']
2901 if kwargs:
2902 raise TclError, 'unknown option -'+kwargs.keys()[0]
2903 menu.add_command(label=value,
2904 command=_setit(variable, value, callback))
2905 for v in values:
2906 menu.add_command(label=v,
2907 command=_setit(variable, v, callback))
2908 self["menu"] = menu
Guido van Rossum28574b51996-10-21 15:16:51 +00002909
Fredrik Lundh06d28152000-08-09 18:03:12 +00002910 def __getitem__(self, name):
2911 if name == 'menu':
2912 return self.__menu
2913 return Widget.__getitem__(self, name)
Guido van Rossum28574b51996-10-21 15:16:51 +00002914
Fredrik Lundh06d28152000-08-09 18:03:12 +00002915 def destroy(self):
2916 """Destroy this widget and the associated menu."""
2917 Menubutton.destroy(self)
2918 self.__menu = None
Guido van Rossumbf4d8f91995-09-01 20:35:37 +00002919
Guido van Rossum35f67fb1995-08-04 03:50:29 +00002920class Image:
Fredrik Lundh06d28152000-08-09 18:03:12 +00002921 """Base class for images."""
Martin v. Löwis0d8ce612000-09-08 16:28:30 +00002922 _last_id = 0
Fredrik Lundh06d28152000-08-09 18:03:12 +00002923 def __init__(self, imgtype, name=None, cnf={}, master=None, **kw):
2924 self.name = None
2925 if not master:
2926 master = _default_root
2927 if not master:
2928 raise RuntimeError, 'Too early to create image'
2929 self.tk = master.tk
2930 if not name:
Martin v. Löwis0d8ce612000-09-08 16:28:30 +00002931 Image._last_id += 1
2932 name = "pyimage" +`Image._last_id` # tk itself would use image<x>
Fredrik Lundh06d28152000-08-09 18:03:12 +00002933 # The following is needed for systems where id(x)
2934 # can return a negative number, such as Linux/m68k:
2935 if name[0] == '-': name = '_' + name[1:]
2936 if kw and cnf: cnf = _cnfmerge((cnf, kw))
2937 elif kw: cnf = kw
2938 options = ()
2939 for k, v in cnf.items():
2940 if callable(v):
2941 v = self._register(v)
2942 options = options + ('-'+k, v)
2943 self.tk.call(('image', 'create', imgtype, name,) + options)
2944 self.name = name
2945 def __str__(self): return self.name
2946 def __del__(self):
2947 if self.name:
2948 try:
2949 self.tk.call('image', 'delete', self.name)
2950 except TclError:
2951 # May happen if the root was destroyed
2952 pass
2953 def __setitem__(self, key, value):
2954 self.tk.call(self.name, 'configure', '-'+key, value)
2955 def __getitem__(self, key):
2956 return self.tk.call(self.name, 'configure', '-'+key)
2957 def configure(self, **kw):
2958 """Configure the image."""
2959 res = ()
2960 for k, v in _cnfmerge(kw).items():
2961 if v is not None:
2962 if k[-1] == '_': k = k[:-1]
2963 if callable(v):
2964 v = self._register(v)
2965 res = res + ('-'+k, v)
2966 self.tk.call((self.name, 'config') + res)
2967 config = configure
2968 def height(self):
2969 """Return the height of the image."""
2970 return getint(
2971 self.tk.call('image', 'height', self.name))
2972 def type(self):
2973 """Return the type of the imgage, e.g. "photo" or "bitmap"."""
2974 return self.tk.call('image', 'type', self.name)
2975 def width(self):
2976 """Return the width of the image."""
2977 return getint(
2978 self.tk.call('image', 'width', self.name))
Guido van Rossum35f67fb1995-08-04 03:50:29 +00002979
2980class PhotoImage(Image):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002981 """Widget which can display colored images in GIF, PPM/PGM format."""
2982 def __init__(self, name=None, cnf={}, master=None, **kw):
2983 """Create an image with NAME.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002984
Fredrik Lundh06d28152000-08-09 18:03:12 +00002985 Valid resource names: data, format, file, gamma, height, palette,
2986 width."""
2987 apply(Image.__init__, (self, 'photo', name, cnf, master), kw)
2988 def blank(self):
2989 """Display a transparent image."""
2990 self.tk.call(self.name, 'blank')
2991 def cget(self, option):
2992 """Return the value of OPTION."""
2993 return self.tk.call(self.name, 'cget', '-' + option)
2994 # XXX config
2995 def __getitem__(self, key):
2996 return self.tk.call(self.name, 'cget', '-' + key)
2997 # XXX copy -from, -to, ...?
2998 def copy(self):
2999 """Return a new PhotoImage with the same image as this widget."""
3000 destImage = PhotoImage()
3001 self.tk.call(destImage, 'copy', self.name)
3002 return destImage
3003 def zoom(self,x,y=''):
3004 """Return a new PhotoImage with the same image as this widget
3005 but zoom it with X and Y."""
3006 destImage = PhotoImage()
3007 if y=='': y=x
3008 self.tk.call(destImage, 'copy', self.name, '-zoom',x,y)
3009 return destImage
3010 def subsample(self,x,y=''):
3011 """Return a new PhotoImage based on the same image as this widget
3012 but use only every Xth or Yth pixel."""
3013 destImage = PhotoImage()
3014 if y=='': y=x
3015 self.tk.call(destImage, 'copy', self.name, '-subsample',x,y)
3016 return destImage
3017 def get(self, x, y):
3018 """Return the color (red, green, blue) of the pixel at X,Y."""
3019 return self.tk.call(self.name, 'get', x, y)
3020 def put(self, data, to=None):
3021 """Put row formated colors to image starting from
3022 position TO, e.g. image.put("{red green} {blue yellow}", to=(4,6))"""
3023 args = (self.name, 'put', data)
3024 if to:
3025 if to[0] == '-to':
3026 to = to[1:]
3027 args = args + ('-to',) + tuple(to)
3028 self.tk.call(args)
3029 # XXX read
3030 def write(self, filename, format=None, from_coords=None):
3031 """Write image to file FILENAME in FORMAT starting from
3032 position FROM_COORDS."""
3033 args = (self.name, 'write', filename)
3034 if format:
3035 args = args + ('-format', format)
3036 if from_coords:
3037 args = args + ('-from',) + tuple(from_coords)
3038 self.tk.call(args)
Guido van Rossum35f67fb1995-08-04 03:50:29 +00003039
3040class BitmapImage(Image):
Fredrik Lundh06d28152000-08-09 18:03:12 +00003041 """Widget which can display a bitmap."""
3042 def __init__(self, name=None, cnf={}, master=None, **kw):
3043 """Create a bitmap with NAME.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00003044
Fredrik Lundh06d28152000-08-09 18:03:12 +00003045 Valid resource names: background, data, file, foreground, maskdata, maskfile."""
3046 apply(Image.__init__, (self, 'bitmap', name, cnf, master), kw)
Guido van Rossum35f67fb1995-08-04 03:50:29 +00003047
3048def image_names(): return _default_root.tk.call('image', 'names')
3049def image_types(): return _default_root.tk.call('image', 'types')
3050
Guido van Rossumaec5dc91994-06-27 07:55:12 +00003051######################################################################
3052# Extensions:
3053
3054class Studbutton(Button):
Fredrik Lundh06d28152000-08-09 18:03:12 +00003055 def __init__(self, master=None, cnf={}, **kw):
3056 Widget.__init__(self, master, 'studbutton', cnf, kw)
3057 self.bind('<Any-Enter>', self.tkButtonEnter)
3058 self.bind('<Any-Leave>', self.tkButtonLeave)
3059 self.bind('<1>', self.tkButtonDown)
3060 self.bind('<ButtonRelease-1>', self.tkButtonUp)
Guido van Rossumaec5dc91994-06-27 07:55:12 +00003061
3062class Tributton(Button):
Fredrik Lundh06d28152000-08-09 18:03:12 +00003063 def __init__(self, master=None, cnf={}, **kw):
3064 Widget.__init__(self, master, 'tributton', cnf, kw)
3065 self.bind('<Any-Enter>', self.tkButtonEnter)
3066 self.bind('<Any-Leave>', self.tkButtonLeave)
3067 self.bind('<1>', self.tkButtonDown)
3068 self.bind('<ButtonRelease-1>', self.tkButtonUp)
3069 self['fg'] = self['bg']
3070 self['activebackground'] = self['bg']
Guido van Rossum37dcab11996-05-16 16:00:19 +00003071
Guido van Rossumc417ef81996-08-21 23:38:59 +00003072######################################################################
3073# Test:
3074
3075def _test():
Fredrik Lundh06d28152000-08-09 18:03:12 +00003076 root = Tk()
3077 text = "This is Tcl/Tk version %s" % TclVersion
3078 if TclVersion >= 8.1:
Fredrik Lundh8fffa202000-08-09 18:51:01 +00003079 try:
3080 text = text + unicode("\nThis should be a cedilla: \347",
3081 "iso-8859-1")
3082 except NameError:
3083 pass # no unicode support
Fredrik Lundh06d28152000-08-09 18:03:12 +00003084 label = Label(root, text=text)
3085 label.pack()
3086 test = Button(root, text="Click me!",
3087 command=lambda root=root: root.test.configure(
3088 text="[%s]" % root.test['text']))
3089 test.pack()
3090 root.test = test
3091 quit = Button(root, text="QUIT", command=root.destroy)
3092 quit.pack()
3093 # The following three commands are needed so the window pops
3094 # up on top on Windows...
3095 root.iconify()
3096 root.update()
3097 root.deiconify()
3098 root.mainloop()
Guido van Rossumc417ef81996-08-21 23:38:59 +00003099
3100if __name__ == '__main__':
Fredrik Lundh06d28152000-08-09 18:03:12 +00003101 _test()