blob: a5a18c44543d2c194166d860d01d7af9d8d026bc [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."""
608 return map(self._nametowidget,
609 self.tk.splitlist(self.tk.call(
610 'winfo', 'children', self._w)))
611 def winfo_class(self):
612 """Return window class name of this widget."""
613 return self.tk.call('winfo', 'class', self._w)
614 def winfo_colormapfull(self):
615 """Return true if at the last color request the colormap was full."""
616 return self.tk.getboolean(
617 self.tk.call('winfo', 'colormapfull', self._w))
618 def winfo_containing(self, rootX, rootY, displayof=0):
619 """Return the widget which is at the root coordinates ROOTX, ROOTY."""
620 args = ('winfo', 'containing') \
621 + self._displayof(displayof) + (rootX, rootY)
622 name = self.tk.call(args)
623 if not name: return None
624 return self._nametowidget(name)
625 def winfo_depth(self):
626 """Return the number of bits per pixel."""
627 return getint(self.tk.call('winfo', 'depth', self._w))
628 def winfo_exists(self):
629 """Return true if this widget exists."""
630 return getint(
631 self.tk.call('winfo', 'exists', self._w))
632 def winfo_fpixels(self, number):
633 """Return the number of pixels for the given distance NUMBER
634 (e.g. "3c") as float."""
635 return getdouble(self.tk.call(
636 'winfo', 'fpixels', self._w, number))
637 def winfo_geometry(self):
638 """Return geometry string for this widget in the form "widthxheight+X+Y"."""
639 return self.tk.call('winfo', 'geometry', self._w)
640 def winfo_height(self):
641 """Return height of this widget."""
642 return getint(
643 self.tk.call('winfo', 'height', self._w))
644 def winfo_id(self):
645 """Return identifier ID for this widget."""
646 return self.tk.getint(
647 self.tk.call('winfo', 'id', self._w))
648 def winfo_interps(self, displayof=0):
649 """Return the name of all Tcl interpreters for this display."""
650 args = ('winfo', 'interps') + self._displayof(displayof)
651 return self.tk.splitlist(self.tk.call(args))
652 def winfo_ismapped(self):
653 """Return true if this widget is mapped."""
654 return getint(
655 self.tk.call('winfo', 'ismapped', self._w))
656 def winfo_manager(self):
657 """Return the window mananger name for this widget."""
658 return self.tk.call('winfo', 'manager', self._w)
659 def winfo_name(self):
660 """Return the name of this widget."""
661 return self.tk.call('winfo', 'name', self._w)
662 def winfo_parent(self):
663 """Return the name of the parent of this widget."""
664 return self.tk.call('winfo', 'parent', self._w)
665 def winfo_pathname(self, id, displayof=0):
666 """Return the pathname of the widget given by ID."""
667 args = ('winfo', 'pathname') \
668 + self._displayof(displayof) + (id,)
669 return self.tk.call(args)
670 def winfo_pixels(self, number):
671 """Rounded integer value of winfo_fpixels."""
672 return getint(
673 self.tk.call('winfo', 'pixels', self._w, number))
674 def winfo_pointerx(self):
675 """Return the x coordinate of the pointer on the root window."""
676 return getint(
677 self.tk.call('winfo', 'pointerx', self._w))
678 def winfo_pointerxy(self):
679 """Return a tuple of x and y coordinates of the pointer on the root window."""
680 return self._getints(
681 self.tk.call('winfo', 'pointerxy', self._w))
682 def winfo_pointery(self):
683 """Return the y coordinate of the pointer on the root window."""
684 return getint(
685 self.tk.call('winfo', 'pointery', self._w))
686 def winfo_reqheight(self):
687 """Return requested height of this widget."""
688 return getint(
689 self.tk.call('winfo', 'reqheight', self._w))
690 def winfo_reqwidth(self):
691 """Return requested width of this widget."""
692 return getint(
693 self.tk.call('winfo', 'reqwidth', self._w))
694 def winfo_rgb(self, color):
695 """Return tuple of decimal values for red, green, blue for
696 COLOR in this widget."""
697 return self._getints(
698 self.tk.call('winfo', 'rgb', self._w, color))
699 def winfo_rootx(self):
700 """Return x coordinate of upper left corner of this widget on the
701 root window."""
702 return getint(
703 self.tk.call('winfo', 'rootx', self._w))
704 def winfo_rooty(self):
705 """Return y coordinate of upper left corner of this widget on the
706 root window."""
707 return getint(
708 self.tk.call('winfo', 'rooty', self._w))
709 def winfo_screen(self):
710 """Return the screen name of this widget."""
711 return self.tk.call('winfo', 'screen', self._w)
712 def winfo_screencells(self):
713 """Return the number of the cells in the colormap of the screen
714 of this widget."""
715 return getint(
716 self.tk.call('winfo', 'screencells', self._w))
717 def winfo_screendepth(self):
718 """Return the number of bits per pixel of the root window of the
719 screen of this widget."""
720 return getint(
721 self.tk.call('winfo', 'screendepth', self._w))
722 def winfo_screenheight(self):
723 """Return the number of pixels of the height of the screen of this widget
724 in pixel."""
725 return getint(
726 self.tk.call('winfo', 'screenheight', self._w))
727 def winfo_screenmmheight(self):
728 """Return the number of pixels of the height of the screen of
729 this widget in mm."""
730 return getint(
731 self.tk.call('winfo', 'screenmmheight', self._w))
732 def winfo_screenmmwidth(self):
733 """Return the number of pixels of the width of the screen of
734 this widget in mm."""
735 return getint(
736 self.tk.call('winfo', 'screenmmwidth', self._w))
737 def winfo_screenvisual(self):
738 """Return one of the strings directcolor, grayscale, pseudocolor,
739 staticcolor, staticgray, or truecolor for the default
740 colormodel of this screen."""
741 return self.tk.call('winfo', 'screenvisual', self._w)
742 def winfo_screenwidth(self):
743 """Return the number of pixels of the width of the screen of
744 this widget in pixel."""
745 return getint(
746 self.tk.call('winfo', 'screenwidth', self._w))
747 def winfo_server(self):
748 """Return information of the X-Server of the screen of this widget in
749 the form "XmajorRminor vendor vendorVersion"."""
750 return self.tk.call('winfo', 'server', self._w)
751 def winfo_toplevel(self):
752 """Return the toplevel widget of this widget."""
753 return self._nametowidget(self.tk.call(
754 'winfo', 'toplevel', self._w))
755 def winfo_viewable(self):
756 """Return true if the widget and all its higher ancestors are mapped."""
757 return getint(
758 self.tk.call('winfo', 'viewable', self._w))
759 def winfo_visual(self):
760 """Return one of the strings directcolor, grayscale, pseudocolor,
761 staticcolor, staticgray, or truecolor for the
762 colormodel of this widget."""
763 return self.tk.call('winfo', 'visual', self._w)
764 def winfo_visualid(self):
765 """Return the X identifier for the visual for this widget."""
766 return self.tk.call('winfo', 'visualid', self._w)
767 def winfo_visualsavailable(self, includeids=0):
768 """Return a list of all visuals available for the screen
769 of this widget.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000770
Fredrik Lundh06d28152000-08-09 18:03:12 +0000771 Each item in the list consists of a visual name (see winfo_visual), a
772 depth and if INCLUDEIDS=1 is given also the X identifier."""
773 data = self.tk.split(
774 self.tk.call('winfo', 'visualsavailable', self._w,
775 includeids and 'includeids' or None))
Fredrik Lundh24037f72000-08-09 19:26:47 +0000776 if type(data) is StringType:
777 data = [self.tk.split(data)]
Fredrik Lundh06d28152000-08-09 18:03:12 +0000778 return map(self.__winfo_parseitem, data)
779 def __winfo_parseitem(self, t):
780 """Internal function."""
781 return t[:1] + tuple(map(self.__winfo_getint, t[1:]))
782 def __winfo_getint(self, x):
783 """Internal function."""
Eric S. Raymondfc170b12001-02-09 11:51:27 +0000784 return int(x, 0)
Fredrik Lundh06d28152000-08-09 18:03:12 +0000785 def winfo_vrootheight(self):
786 """Return the height of the virtual root window associated with this
787 widget in pixels. If there is no virtual root window return the
788 height of the screen."""
789 return getint(
790 self.tk.call('winfo', 'vrootheight', self._w))
791 def winfo_vrootwidth(self):
792 """Return the width of the virtual root window associated with this
793 widget in pixel. If there is no virtual root window return the
794 width of the screen."""
795 return getint(
796 self.tk.call('winfo', 'vrootwidth', self._w))
797 def winfo_vrootx(self):
798 """Return the x offset of the virtual root relative to the root
799 window of the screen of this widget."""
800 return getint(
801 self.tk.call('winfo', 'vrootx', self._w))
802 def winfo_vrooty(self):
803 """Return the y offset of the virtual root relative to the root
804 window of the screen of this widget."""
805 return getint(
806 self.tk.call('winfo', 'vrooty', self._w))
807 def winfo_width(self):
808 """Return the width of this widget."""
809 return getint(
810 self.tk.call('winfo', 'width', self._w))
811 def winfo_x(self):
812 """Return the x coordinate of the upper left corner of this widget
813 in the parent."""
814 return getint(
815 self.tk.call('winfo', 'x', self._w))
816 def winfo_y(self):
817 """Return the y coordinate of the upper left corner of this widget
818 in the parent."""
819 return getint(
820 self.tk.call('winfo', 'y', self._w))
821 def update(self):
822 """Enter event loop until all pending events have been processed by Tcl."""
823 self.tk.call('update')
824 def update_idletasks(self):
825 """Enter event loop until all idle callbacks have been called. This
826 will update the display of windows but not process events caused by
827 the user."""
828 self.tk.call('update', 'idletasks')
829 def bindtags(self, tagList=None):
830 """Set or get the list of bindtags for this widget.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000831
Fredrik Lundh06d28152000-08-09 18:03:12 +0000832 With no argument return the list of all bindtags associated with
833 this widget. With a list of strings as argument the bindtags are
834 set to this list. The bindtags determine in which order events are
835 processed (see bind)."""
836 if tagList is None:
837 return self.tk.splitlist(
838 self.tk.call('bindtags', self._w))
839 else:
840 self.tk.call('bindtags', self._w, tagList)
841 def _bind(self, what, sequence, func, add, needcleanup=1):
842 """Internal function."""
843 if type(func) is StringType:
844 self.tk.call(what + (sequence, func))
845 elif func:
846 funcid = self._register(func, self._substitute,
847 needcleanup)
848 cmd = ('%sif {"[%s %s]" == "break"} break\n'
849 %
850 (add and '+' or '',
Martin v. Löwisc8718c12001-08-09 16:57:33 +0000851 funcid, self._subst_format_str))
Fredrik Lundh06d28152000-08-09 18:03:12 +0000852 self.tk.call(what + (sequence, cmd))
853 return funcid
854 elif sequence:
855 return self.tk.call(what + (sequence,))
856 else:
857 return self.tk.splitlist(self.tk.call(what))
858 def bind(self, sequence=None, func=None, add=None):
859 """Bind to this widget at event SEQUENCE a call to function FUNC.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000860
Fredrik Lundh06d28152000-08-09 18:03:12 +0000861 SEQUENCE is a string of concatenated event
862 patterns. An event pattern is of the form
863 <MODIFIER-MODIFIER-TYPE-DETAIL> where MODIFIER is one
864 of Control, Mod2, M2, Shift, Mod3, M3, Lock, Mod4, M4,
865 Button1, B1, Mod5, M5 Button2, B2, Meta, M, Button3,
866 B3, Alt, Button4, B4, Double, Button5, B5 Triple,
867 Mod1, M1. TYPE is one of Activate, Enter, Map,
868 ButtonPress, Button, Expose, Motion, ButtonRelease
869 FocusIn, MouseWheel, Circulate, FocusOut, Property,
870 Colormap, Gravity Reparent, Configure, KeyPress, Key,
871 Unmap, Deactivate, KeyRelease Visibility, Destroy,
872 Leave and DETAIL is the button number for ButtonPress,
873 ButtonRelease and DETAIL is the Keysym for KeyPress and
874 KeyRelease. Examples are
875 <Control-Button-1> for pressing Control and mouse button 1 or
876 <Alt-A> for pressing A and the Alt key (KeyPress can be omitted).
877 An event pattern can also be a virtual event of the form
878 <<AString>> where AString can be arbitrary. This
879 event can be generated by event_generate.
880 If events are concatenated they must appear shortly
881 after each other.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000882
Fredrik Lundh06d28152000-08-09 18:03:12 +0000883 FUNC will be called if the event sequence occurs with an
884 instance of Event as argument. If the return value of FUNC is
885 "break" no further bound function is invoked.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000886
Fredrik Lundh06d28152000-08-09 18:03:12 +0000887 An additional boolean parameter ADD specifies whether FUNC will
888 be called additionally to the other bound function or whether
889 it will replace the previous function.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000890
Fredrik Lundh06d28152000-08-09 18:03:12 +0000891 Bind will return an identifier to allow deletion of the bound function with
892 unbind without memory leak.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000893
Fredrik Lundh06d28152000-08-09 18:03:12 +0000894 If FUNC or SEQUENCE is omitted the bound function or list
895 of bound events are returned."""
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000896
Fredrik Lundh06d28152000-08-09 18:03:12 +0000897 return self._bind(('bind', self._w), sequence, func, add)
898 def unbind(self, sequence, funcid=None):
899 """Unbind for this widget for event SEQUENCE the
900 function identified with FUNCID."""
901 self.tk.call('bind', self._w, sequence, '')
902 if funcid:
903 self.deletecommand(funcid)
904 def bind_all(self, sequence=None, func=None, add=None):
905 """Bind to all widgets at an event SEQUENCE a call to function FUNC.
906 An additional boolean parameter ADD specifies whether FUNC will
907 be called additionally to the other bound function or whether
908 it will replace the previous function. See bind for the return value."""
909 return self._bind(('bind', 'all'), sequence, func, add, 0)
910 def unbind_all(self, sequence):
911 """Unbind for all widgets for event SEQUENCE all functions."""
912 self.tk.call('bind', 'all' , sequence, '')
913 def bind_class(self, className, sequence=None, func=None, add=None):
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000914
Fredrik Lundh06d28152000-08-09 18:03:12 +0000915 """Bind to widgets with bindtag CLASSNAME at event
916 SEQUENCE a call of function FUNC. An additional
917 boolean parameter ADD specifies whether FUNC will be
918 called additionally to the other bound function or
919 whether it will replace the previous function. See bind for
920 the return value."""
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000921
Fredrik Lundh06d28152000-08-09 18:03:12 +0000922 return self._bind(('bind', className), sequence, func, add, 0)
923 def unbind_class(self, className, sequence):
924 """Unbind for a all widgets with bindtag CLASSNAME for event SEQUENCE
925 all functions."""
926 self.tk.call('bind', className , sequence, '')
927 def mainloop(self, n=0):
928 """Call the mainloop of Tk."""
929 self.tk.mainloop(n)
930 def quit(self):
931 """Quit the Tcl interpreter. All widgets will be destroyed."""
932 self.tk.quit()
933 def _getints(self, string):
934 """Internal function."""
935 if string:
936 return tuple(map(getint, self.tk.splitlist(string)))
937 def _getdoubles(self, string):
938 """Internal function."""
939 if string:
940 return tuple(map(getdouble, self.tk.splitlist(string)))
941 def _getboolean(self, string):
942 """Internal function."""
943 if string:
944 return self.tk.getboolean(string)
945 def _displayof(self, displayof):
946 """Internal function."""
947 if displayof:
948 return ('-displayof', displayof)
949 if displayof is None:
950 return ('-displayof', self._w)
951 return ()
952 def _options(self, cnf, kw = None):
953 """Internal function."""
954 if kw:
955 cnf = _cnfmerge((cnf, kw))
956 else:
957 cnf = _cnfmerge(cnf)
958 res = ()
959 for k, v in cnf.items():
960 if v is not None:
961 if k[-1] == '_': k = k[:-1]
962 if callable(v):
963 v = self._register(v)
964 res = res + ('-'+k, v)
965 return res
966 def nametowidget(self, name):
967 """Return the Tkinter instance of a widget identified by
968 its Tcl name NAME."""
969 w = self
970 if name[0] == '.':
971 w = w._root()
972 name = name[1:]
Fredrik Lundh06d28152000-08-09 18:03:12 +0000973 while name:
Eric S. Raymondfc170b12001-02-09 11:51:27 +0000974 i = name.find('.')
Fredrik Lundh06d28152000-08-09 18:03:12 +0000975 if i >= 0:
976 name, tail = name[:i], name[i+1:]
977 else:
978 tail = ''
979 w = w.children[name]
980 name = tail
981 return w
982 _nametowidget = nametowidget
983 def _register(self, func, subst=None, needcleanup=1):
984 """Return a newly created Tcl function. If this
985 function is called, the Python function FUNC will
986 be executed. An optional function SUBST can
987 be given which will be executed before FUNC."""
988 f = CallWrapper(func, subst, self).__call__
989 name = `id(f)`
990 try:
991 func = func.im_func
992 except AttributeError:
993 pass
994 try:
995 name = name + func.__name__
996 except AttributeError:
997 pass
998 self.tk.createcommand(name, f)
999 if needcleanup:
1000 if self._tclCommands is None:
1001 self._tclCommands = []
1002 self._tclCommands.append(name)
1003 #print '+ Tkinter created command', name
1004 return name
1005 register = _register
1006 def _root(self):
1007 """Internal function."""
1008 w = self
1009 while w.master: w = w.master
1010 return w
1011 _subst_format = ('%#', '%b', '%f', '%h', '%k',
1012 '%s', '%t', '%w', '%x', '%y',
1013 '%A', '%E', '%K', '%N', '%W', '%T', '%X', '%Y', '%D')
Martin v. Löwisc8718c12001-08-09 16:57:33 +00001014 _subst_format_str = " ".join(_subst_format)
Fredrik Lundh06d28152000-08-09 18:03:12 +00001015 def _substitute(self, *args):
1016 """Internal function."""
1017 if len(args) != len(self._subst_format): return args
1018 getboolean = self.tk.getboolean
1019 getint = int
1020 nsign, b, f, h, k, s, t, w, x, y, A, E, K, N, W, T, X, Y, D = args
1021 # Missing: (a, c, d, m, o, v, B, R)
1022 e = Event()
1023 e.serial = getint(nsign)
1024 e.num = getint(b)
1025 try: e.focus = getboolean(f)
1026 except TclError: pass
1027 e.height = getint(h)
1028 e.keycode = getint(k)
1029 # For Visibility events, event state is a string and
1030 # not an integer:
1031 try:
1032 e.state = getint(s)
1033 except ValueError:
1034 e.state = s
1035 e.time = getint(t)
1036 e.width = getint(w)
1037 e.x = getint(x)
1038 e.y = getint(y)
1039 e.char = A
1040 try: e.send_event = getboolean(E)
1041 except TclError: pass
1042 e.keysym = K
1043 e.keysym_num = getint(N)
1044 e.type = T
1045 try:
1046 e.widget = self._nametowidget(W)
1047 except KeyError:
1048 e.widget = W
1049 e.x_root = getint(X)
1050 e.y_root = getint(Y)
Fredrik Lundha249f162000-09-07 15:05:09 +00001051 try:
1052 e.delta = getint(D)
1053 except ValueError:
1054 e.delta = 0
Fredrik Lundh06d28152000-08-09 18:03:12 +00001055 return (e,)
1056 def _report_exception(self):
1057 """Internal function."""
1058 import sys
1059 exc, val, tb = sys.exc_type, sys.exc_value, sys.exc_traceback
1060 root = self._root()
1061 root.report_callback_exception(exc, val, tb)
1062 # These used to be defined in Widget:
1063 def configure(self, cnf=None, **kw):
1064 """Configure resources of a widget.
Barry Warsaw107e6231998-12-15 00:44:15 +00001065
Fredrik Lundh06d28152000-08-09 18:03:12 +00001066 The values for resources are specified as keyword
1067 arguments. To get an overview about
1068 the allowed keyword arguments call the method keys.
1069 """
1070 # XXX ought to generalize this so tag_config etc. can use it
1071 if kw:
1072 cnf = _cnfmerge((cnf, kw))
1073 elif cnf:
1074 cnf = _cnfmerge(cnf)
1075 if cnf is None:
1076 cnf = {}
1077 for x in self.tk.split(
1078 self.tk.call(self._w, 'configure')):
1079 cnf[x[0][1:]] = (x[0][1:],) + x[1:]
1080 return cnf
1081 if type(cnf) is StringType:
1082 x = self.tk.split(self.tk.call(
1083 self._w, 'configure', '-'+cnf))
1084 return (x[0][1:],) + x[1:]
1085 self.tk.call((self._w, 'configure')
1086 + self._options(cnf))
1087 config = configure
1088 def cget(self, key):
1089 """Return the resource value for a KEY given as string."""
1090 return self.tk.call(self._w, 'cget', '-' + key)
1091 __getitem__ = cget
1092 def __setitem__(self, key, value):
1093 self.configure({key: value})
1094 def keys(self):
1095 """Return a list of all resource names of this widget."""
1096 return map(lambda x: x[0][1:],
1097 self.tk.split(self.tk.call(self._w, 'configure')))
1098 def __str__(self):
1099 """Return the window path name of this widget."""
1100 return self._w
1101 # Pack methods that apply to the master
1102 _noarg_ = ['_noarg_']
1103 def pack_propagate(self, flag=_noarg_):
1104 """Set or get the status for propagation of geometry information.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001105
Fredrik Lundh06d28152000-08-09 18:03:12 +00001106 A boolean argument specifies whether the geometry information
1107 of the slaves will determine the size of this widget. If no argument
1108 is given the current setting will be returned.
1109 """
1110 if flag is Misc._noarg_:
1111 return self._getboolean(self.tk.call(
1112 'pack', 'propagate', self._w))
1113 else:
1114 self.tk.call('pack', 'propagate', self._w, flag)
1115 propagate = pack_propagate
1116 def pack_slaves(self):
1117 """Return a list of all slaves of this widget
1118 in its packing order."""
1119 return map(self._nametowidget,
1120 self.tk.splitlist(
1121 self.tk.call('pack', 'slaves', self._w)))
1122 slaves = pack_slaves
1123 # Place method that applies to the master
1124 def place_slaves(self):
1125 """Return a list of all slaves of this widget
1126 in its packing order."""
1127 return map(self._nametowidget,
1128 self.tk.splitlist(
1129 self.tk.call(
1130 'place', 'slaves', self._w)))
1131 # Grid methods that apply to the master
1132 def grid_bbox(self, column=None, row=None, col2=None, row2=None):
1133 """Return a tuple of integer coordinates for the bounding
1134 box of this widget controlled by the geometry manager grid.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001135
Fredrik Lundh06d28152000-08-09 18:03:12 +00001136 If COLUMN, ROW is given the bounding box applies from
1137 the cell with row and column 0 to the specified
1138 cell. If COL2 and ROW2 are given the bounding box
1139 starts at that cell.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001140
Fredrik Lundh06d28152000-08-09 18:03:12 +00001141 The returned integers specify the offset of the upper left
1142 corner in the master widget and the width and height.
1143 """
1144 args = ('grid', 'bbox', self._w)
1145 if column is not None and row is not None:
1146 args = args + (column, row)
1147 if col2 is not None and row2 is not None:
1148 args = args + (col2, row2)
1149 return self._getints(apply(self.tk.call, args)) or None
Guido van Rossum18468821994-06-20 07:49:28 +00001150
Fredrik Lundh06d28152000-08-09 18:03:12 +00001151 bbox = grid_bbox
1152 def _grid_configure(self, command, index, cnf, kw):
1153 """Internal function."""
1154 if type(cnf) is StringType and not kw:
1155 if cnf[-1:] == '_':
1156 cnf = cnf[:-1]
1157 if cnf[:1] != '-':
1158 cnf = '-'+cnf
1159 options = (cnf,)
1160 else:
1161 options = self._options(cnf, kw)
1162 if not options:
1163 res = self.tk.call('grid',
1164 command, self._w, index)
1165 words = self.tk.splitlist(res)
1166 dict = {}
1167 for i in range(0, len(words), 2):
1168 key = words[i][1:]
1169 value = words[i+1]
1170 if not value:
1171 value = None
1172 elif '.' in value:
1173 value = getdouble(value)
1174 else:
1175 value = getint(value)
1176 dict[key] = value
1177 return dict
1178 res = self.tk.call(
1179 ('grid', command, self._w, index)
1180 + options)
1181 if len(options) == 1:
1182 if not res: return None
1183 # In Tk 7.5, -width can be a float
1184 if '.' in res: return getdouble(res)
1185 return getint(res)
1186 def grid_columnconfigure(self, index, cnf={}, **kw):
1187 """Configure column INDEX of a grid.
Guido van Rossum80f8be81997-12-02 19:51:39 +00001188
Fredrik Lundh06d28152000-08-09 18:03:12 +00001189 Valid resources are minsize (minimum size of the column),
1190 weight (how much does additional space propagate to this column)
1191 and pad (how much space to let additionally)."""
1192 return self._grid_configure('columnconfigure', index, cnf, kw)
1193 columnconfigure = grid_columnconfigure
1194 def grid_propagate(self, flag=_noarg_):
1195 """Set or get the status for propagation of geometry information.
Guido van Rossum80f8be81997-12-02 19:51:39 +00001196
Fredrik Lundh06d28152000-08-09 18:03:12 +00001197 A boolean argument specifies whether the geometry information
1198 of the slaves will determine the size of this widget. If no argument
1199 is given, the current setting will be returned.
1200 """
1201 if flag is Misc._noarg_:
1202 return self._getboolean(self.tk.call(
1203 'grid', 'propagate', self._w))
1204 else:
1205 self.tk.call('grid', 'propagate', self._w, flag)
1206 def grid_rowconfigure(self, index, cnf={}, **kw):
1207 """Configure row INDEX of a grid.
Guido van Rossum80f8be81997-12-02 19:51:39 +00001208
Fredrik Lundh06d28152000-08-09 18:03:12 +00001209 Valid resources are minsize (minimum size of the row),
1210 weight (how much does additional space propagate to this row)
1211 and pad (how much space to let additionally)."""
1212 return self._grid_configure('rowconfigure', index, cnf, kw)
1213 rowconfigure = grid_rowconfigure
1214 def grid_size(self):
1215 """Return a tuple of the number of column and rows in the grid."""
1216 return self._getints(
1217 self.tk.call('grid', 'size', self._w)) or None
1218 size = grid_size
1219 def grid_slaves(self, row=None, column=None):
1220 """Return a list of all slaves of this widget
1221 in its packing order."""
1222 args = ()
1223 if row is not None:
1224 args = args + ('-row', row)
1225 if column is not None:
1226 args = args + ('-column', column)
1227 return map(self._nametowidget,
1228 self.tk.splitlist(self.tk.call(
1229 ('grid', 'slaves', self._w) + args)))
Guido van Rossum80f8be81997-12-02 19:51:39 +00001230
Fredrik Lundh06d28152000-08-09 18:03:12 +00001231 # Support for the "event" command, new in Tk 4.2.
1232 # By Case Roole.
Guido van Rossum80f8be81997-12-02 19:51:39 +00001233
Fredrik Lundh06d28152000-08-09 18:03:12 +00001234 def event_add(self, virtual, *sequences):
1235 """Bind a virtual event VIRTUAL (of the form <<Name>>)
1236 to an event SEQUENCE such that the virtual event is triggered
1237 whenever SEQUENCE occurs."""
1238 args = ('event', 'add', virtual) + sequences
1239 self.tk.call(args)
Guido van Rossumc2966511998-04-10 19:16:10 +00001240
Fredrik Lundh06d28152000-08-09 18:03:12 +00001241 def event_delete(self, virtual, *sequences):
1242 """Unbind a virtual event VIRTUAL from SEQUENCE."""
1243 args = ('event', 'delete', virtual) + sequences
1244 self.tk.call(args)
Guido van Rossumc2966511998-04-10 19:16:10 +00001245
Fredrik Lundh06d28152000-08-09 18:03:12 +00001246 def event_generate(self, sequence, **kw):
1247 """Generate an event SEQUENCE. Additional
1248 keyword arguments specify parameter of the event
1249 (e.g. x, y, rootx, rooty)."""
1250 args = ('event', 'generate', self._w, sequence)
1251 for k, v in kw.items():
1252 args = args + ('-%s' % k, str(v))
1253 self.tk.call(args)
1254
1255 def event_info(self, virtual=None):
1256 """Return a list of all virtual events or the information
1257 about the SEQUENCE bound to the virtual event VIRTUAL."""
1258 return self.tk.splitlist(
1259 self.tk.call('event', 'info', virtual))
1260
1261 # Image related commands
1262
1263 def image_names(self):
1264 """Return a list of all existing image names."""
1265 return self.tk.call('image', 'names')
1266
1267 def image_types(self):
1268 """Return a list of all available image types (e.g. phote bitmap)."""
1269 return self.tk.call('image', 'types')
Guido van Rossumc2966511998-04-10 19:16:10 +00001270
Guido van Rossum80f8be81997-12-02 19:51:39 +00001271
Guido van Rossuma5773dd1995-09-07 19:22:00 +00001272class CallWrapper:
Fredrik Lundh06d28152000-08-09 18:03:12 +00001273 """Internal class. Stores function to call when some user
1274 defined Tcl function is called e.g. after an event occurred."""
1275 def __init__(self, func, subst, widget):
1276 """Store FUNC, SUBST and WIDGET as members."""
1277 self.func = func
1278 self.subst = subst
1279 self.widget = widget
1280 def __call__(self, *args):
1281 """Apply first function SUBST to arguments, than FUNC."""
1282 try:
1283 if self.subst:
1284 args = apply(self.subst, args)
1285 return apply(self.func, args)
1286 except SystemExit, msg:
1287 raise SystemExit, msg
1288 except:
1289 self.widget._report_exception()
Guido van Rossum18468821994-06-20 07:49:28 +00001290
Guido van Rossume365a591998-05-01 19:48:20 +00001291
Guido van Rossum18468821994-06-20 07:49:28 +00001292class Wm:
Fredrik Lundh06d28152000-08-09 18:03:12 +00001293 """Provides functions for the communication with the window manager."""
1294 def wm_aspect(self,
1295 minNumer=None, minDenom=None,
1296 maxNumer=None, maxDenom=None):
1297 """Instruct the window manager to set the aspect ratio (width/height)
1298 of this widget to be between MINNUMER/MINDENOM and MAXNUMER/MAXDENOM. Return a tuple
1299 of the actual values if no argument is given."""
1300 return self._getints(
1301 self.tk.call('wm', 'aspect', self._w,
1302 minNumer, minDenom,
1303 maxNumer, maxDenom))
1304 aspect = wm_aspect
1305 def wm_client(self, name=None):
1306 """Store NAME in WM_CLIENT_MACHINE property of this widget. Return
1307 current value."""
1308 return self.tk.call('wm', 'client', self._w, name)
1309 client = wm_client
1310 def wm_colormapwindows(self, *wlist):
1311 """Store list of window names (WLIST) into WM_COLORMAPWINDOWS property
1312 of this widget. This list contains windows whose colormaps differ from their
1313 parents. Return current list of widgets if WLIST is empty."""
1314 if len(wlist) > 1:
1315 wlist = (wlist,) # Tk needs a list of windows here
1316 args = ('wm', 'colormapwindows', self._w) + wlist
1317 return map(self._nametowidget, self.tk.call(args))
1318 colormapwindows = wm_colormapwindows
1319 def wm_command(self, value=None):
1320 """Store VALUE in WM_COMMAND property. It is the command
1321 which shall be used to invoke the application. Return current
1322 command if VALUE is None."""
1323 return self.tk.call('wm', 'command', self._w, value)
1324 command = wm_command
1325 def wm_deiconify(self):
1326 """Deiconify this widget. If it was never mapped it will not be mapped.
1327 On Windows it will raise this widget and give it the focus."""
1328 return self.tk.call('wm', 'deiconify', self._w)
1329 deiconify = wm_deiconify
1330 def wm_focusmodel(self, model=None):
1331 """Set focus model to MODEL. "active" means that this widget will claim
1332 the focus itself, "passive" means that the window manager shall give
1333 the focus. Return current focus model if MODEL is None."""
1334 return self.tk.call('wm', 'focusmodel', self._w, model)
1335 focusmodel = wm_focusmodel
1336 def wm_frame(self):
1337 """Return identifier for decorative frame of this widget if present."""
1338 return self.tk.call('wm', 'frame', self._w)
1339 frame = wm_frame
1340 def wm_geometry(self, newGeometry=None):
1341 """Set geometry to NEWGEOMETRY of the form =widthxheight+x+y. Return
1342 current value if None is given."""
1343 return self.tk.call('wm', 'geometry', self._w, newGeometry)
1344 geometry = wm_geometry
1345 def wm_grid(self,
1346 baseWidth=None, baseHeight=None,
1347 widthInc=None, heightInc=None):
1348 """Instruct the window manager that this widget shall only be
1349 resized on grid boundaries. WIDTHINC and HEIGHTINC are the width and
1350 height of a grid unit in pixels. BASEWIDTH and BASEHEIGHT are the
1351 number of grid units requested in Tk_GeometryRequest."""
1352 return self._getints(self.tk.call(
1353 'wm', 'grid', self._w,
1354 baseWidth, baseHeight, widthInc, heightInc))
1355 grid = wm_grid
1356 def wm_group(self, pathName=None):
1357 """Set the group leader widgets for related widgets to PATHNAME. Return
1358 the group leader of this widget if None is given."""
1359 return self.tk.call('wm', 'group', self._w, pathName)
1360 group = wm_group
1361 def wm_iconbitmap(self, bitmap=None):
1362 """Set bitmap for the iconified widget to BITMAP. Return
1363 the bitmap if None is given."""
1364 return self.tk.call('wm', 'iconbitmap', self._w, bitmap)
1365 iconbitmap = wm_iconbitmap
1366 def wm_iconify(self):
1367 """Display widget as icon."""
1368 return self.tk.call('wm', 'iconify', self._w)
1369 iconify = wm_iconify
1370 def wm_iconmask(self, bitmap=None):
1371 """Set mask for the icon bitmap of this widget. Return the
1372 mask if None is given."""
1373 return self.tk.call('wm', 'iconmask', self._w, bitmap)
1374 iconmask = wm_iconmask
1375 def wm_iconname(self, newName=None):
1376 """Set the name of the icon for this widget. Return the name if
1377 None is given."""
1378 return self.tk.call('wm', 'iconname', self._w, newName)
1379 iconname = wm_iconname
1380 def wm_iconposition(self, x=None, y=None):
1381 """Set the position of the icon of this widget to X and Y. Return
1382 a tuple of the current values of X and X if None is given."""
1383 return self._getints(self.tk.call(
1384 'wm', 'iconposition', self._w, x, y))
1385 iconposition = wm_iconposition
1386 def wm_iconwindow(self, pathName=None):
1387 """Set widget PATHNAME to be displayed instead of icon. Return the current
1388 value if None is given."""
1389 return self.tk.call('wm', 'iconwindow', self._w, pathName)
1390 iconwindow = wm_iconwindow
1391 def wm_maxsize(self, width=None, height=None):
1392 """Set max WIDTH and HEIGHT for this widget. If the window is gridded
1393 the values are given in grid units. Return the current values if None
1394 is given."""
1395 return self._getints(self.tk.call(
1396 'wm', 'maxsize', self._w, width, height))
1397 maxsize = wm_maxsize
1398 def wm_minsize(self, width=None, height=None):
1399 """Set min WIDTH and HEIGHT for this widget. If the window is gridded
1400 the values are given in grid units. Return the current values if None
1401 is given."""
1402 return self._getints(self.tk.call(
1403 'wm', 'minsize', self._w, width, height))
1404 minsize = wm_minsize
1405 def wm_overrideredirect(self, boolean=None):
1406 """Instruct the window manager to ignore this widget
1407 if BOOLEAN is given with 1. Return the current value if None
1408 is given."""
1409 return self._getboolean(self.tk.call(
1410 'wm', 'overrideredirect', self._w, boolean))
1411 overrideredirect = wm_overrideredirect
1412 def wm_positionfrom(self, who=None):
1413 """Instruct the window manager that the position of this widget shall
1414 be defined by the user if WHO is "user", and by its own policy if WHO is
1415 "program"."""
1416 return self.tk.call('wm', 'positionfrom', self._w, who)
1417 positionfrom = wm_positionfrom
1418 def wm_protocol(self, name=None, func=None):
1419 """Bind function FUNC to command NAME for this widget.
1420 Return the function bound to NAME if None is given. NAME could be
1421 e.g. "WM_SAVE_YOURSELF" or "WM_DELETE_WINDOW"."""
1422 if callable(func):
1423 command = self._register(func)
1424 else:
1425 command = func
1426 return self.tk.call(
1427 'wm', 'protocol', self._w, name, command)
1428 protocol = wm_protocol
1429 def wm_resizable(self, width=None, height=None):
1430 """Instruct the window manager whether this width can be resized
1431 in WIDTH or HEIGHT. Both values are boolean values."""
1432 return self.tk.call('wm', 'resizable', self._w, width, height)
1433 resizable = wm_resizable
1434 def wm_sizefrom(self, who=None):
1435 """Instruct the window manager that the size of this widget shall
1436 be defined by the user if WHO is "user", and by its own policy if WHO is
1437 "program"."""
1438 return self.tk.call('wm', 'sizefrom', self._w, who)
1439 sizefrom = wm_sizefrom
Fredrik Lundh289ad8f2000-08-09 19:11:59 +00001440 def wm_state(self, newstate=None):
1441 """Query or set the state of this widget as one of normal, icon,
1442 iconic (see wm_iconwindow), withdrawn, or zoomed (Windows only)."""
1443 return self.tk.call('wm', 'state', self._w, newstate)
Fredrik Lundh06d28152000-08-09 18:03:12 +00001444 state = wm_state
1445 def wm_title(self, string=None):
1446 """Set the title of this widget."""
1447 return self.tk.call('wm', 'title', self._w, string)
1448 title = wm_title
1449 def wm_transient(self, master=None):
1450 """Instruct the window manager that this widget is transient
1451 with regard to widget MASTER."""
1452 return self.tk.call('wm', 'transient', self._w, master)
1453 transient = wm_transient
1454 def wm_withdraw(self):
1455 """Withdraw this widget from the screen such that it is unmapped
1456 and forgotten by the window manager. Re-draw it with wm_deiconify."""
1457 return self.tk.call('wm', 'withdraw', self._w)
1458 withdraw = wm_withdraw
Guido van Rossume365a591998-05-01 19:48:20 +00001459
Guido van Rossum18468821994-06-20 07:49:28 +00001460
1461class Tk(Misc, Wm):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001462 """Toplevel widget of Tk which represents mostly the main window
1463 of an appliation. It has an associated Tcl interpreter."""
1464 _w = '.'
1465 def __init__(self, screenName=None, baseName=None, className='Tk'):
1466 """Return a new Toplevel widget on screen SCREENNAME. A new Tcl interpreter will
1467 be created. BASENAME will be used for the identification of the profile file (see
1468 readprofile).
1469 It is constructed from sys.argv[0] without extensions if None is given. CLASSNAME
1470 is the name of the widget class."""
1471 global _default_root
1472 self.master = None
1473 self.children = {}
1474 if baseName is None:
1475 import sys, os
1476 baseName = os.path.basename(sys.argv[0])
1477 baseName, ext = os.path.splitext(baseName)
1478 if ext not in ('.py', '.pyc', '.pyo'):
1479 baseName = baseName + ext
1480 self.tk = _tkinter.create(screenName, baseName, className)
Jack Jansenbe92af02001-08-23 13:25:59 +00001481 if _MacOS and hasattr(_MacOS, 'SchedParams'):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001482 # Disable event scanning except for Command-Period
1483 _MacOS.SchedParams(1, 0)
1484 # Work around nasty MacTk bug
1485 # XXX Is this one still needed?
1486 self.update()
1487 # Version sanity checks
1488 tk_version = self.tk.getvar('tk_version')
1489 if tk_version != _tkinter.TK_VERSION:
1490 raise RuntimeError, \
1491 "tk.h version (%s) doesn't match libtk.a version (%s)" \
1492 % (_tkinter.TK_VERSION, tk_version)
1493 tcl_version = self.tk.getvar('tcl_version')
1494 if tcl_version != _tkinter.TCL_VERSION:
1495 raise RuntimeError, \
1496 "tcl.h version (%s) doesn't match libtcl.a version (%s)" \
1497 % (_tkinter.TCL_VERSION, tcl_version)
1498 if TkVersion < 4.0:
1499 raise RuntimeError, \
1500 "Tk 4.0 or higher is required; found Tk %s" \
1501 % str(TkVersion)
1502 self.tk.createcommand('tkerror', _tkerror)
1503 self.tk.createcommand('exit', _exit)
1504 self.readprofile(baseName, className)
1505 if _support_default_root and not _default_root:
1506 _default_root = self
1507 self.protocol("WM_DELETE_WINDOW", self.destroy)
1508 def destroy(self):
1509 """Destroy this and all descendants widgets. This will
1510 end the application of this Tcl interpreter."""
1511 for c in self.children.values(): c.destroy()
1512 self.tk.call('destroy', self._w)
1513 Misc.destroy(self)
1514 global _default_root
1515 if _support_default_root and _default_root is self:
1516 _default_root = None
1517 def readprofile(self, baseName, className):
1518 """Internal function. It reads BASENAME.tcl and CLASSNAME.tcl into
1519 the Tcl Interpreter and calls execfile on BASENAME.py and CLASSNAME.py if
1520 such a file exists in the home directory."""
1521 import os
1522 if os.environ.has_key('HOME'): home = os.environ['HOME']
1523 else: home = os.curdir
1524 class_tcl = os.path.join(home, '.%s.tcl' % className)
1525 class_py = os.path.join(home, '.%s.py' % className)
1526 base_tcl = os.path.join(home, '.%s.tcl' % baseName)
1527 base_py = os.path.join(home, '.%s.py' % baseName)
1528 dir = {'self': self}
1529 exec 'from Tkinter import *' in dir
1530 if os.path.isfile(class_tcl):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001531 self.tk.call('source', class_tcl)
1532 if os.path.isfile(class_py):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001533 execfile(class_py, dir)
1534 if os.path.isfile(base_tcl):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001535 self.tk.call('source', base_tcl)
1536 if os.path.isfile(base_py):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001537 execfile(base_py, dir)
1538 def report_callback_exception(self, exc, val, tb):
1539 """Internal function. It reports exception on sys.stderr."""
1540 import traceback, sys
1541 sys.stderr.write("Exception in Tkinter callback\n")
1542 sys.last_type = exc
1543 sys.last_value = val
1544 sys.last_traceback = tb
1545 traceback.print_exception(exc, val, tb)
Guido van Rossum18468821994-06-20 07:49:28 +00001546
Guido van Rossum368e06b1997-11-07 20:38:49 +00001547# Ideally, the classes Pack, Place and Grid disappear, the
1548# pack/place/grid methods are defined on the Widget class, and
1549# everybody uses w.pack_whatever(...) instead of Pack.whatever(w,
1550# ...), with pack(), place() and grid() being short for
1551# pack_configure(), place_configure() and grid_columnconfigure(), and
1552# forget() being short for pack_forget(). As a practical matter, I'm
1553# afraid that there is too much code out there that may be using the
1554# Pack, Place or Grid class, so I leave them intact -- but only as
1555# backwards compatibility features. Also note that those methods that
1556# take a master as argument (e.g. pack_propagate) have been moved to
1557# the Misc class (which now incorporates all methods common between
1558# toplevel and interior widgets). Again, for compatibility, these are
1559# copied into the Pack, Place or Grid class.
1560
Guido van Rossum18468821994-06-20 07:49:28 +00001561class Pack:
Fredrik Lundh06d28152000-08-09 18:03:12 +00001562 """Geometry manager Pack.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001563
Fredrik Lundh06d28152000-08-09 18:03:12 +00001564 Base class to use the methods pack_* in every widget."""
1565 def pack_configure(self, cnf={}, **kw):
1566 """Pack a widget in the parent widget. Use as options:
1567 after=widget - pack it after you have packed widget
1568 anchor=NSEW (or subset) - position widget according to
1569 given direction
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001570 before=widget - pack it before you will pack widget
Fredrik Lundh06d28152000-08-09 18:03:12 +00001571 expand=1 or 0 - expand widget if parent size grows
1572 fill=NONE or X or Y or BOTH - fill widget if widget grows
1573 in=master - use master to contain this widget
1574 ipadx=amount - add internal padding in x direction
1575 ipady=amount - add internal padding in y direction
1576 padx=amount - add padding in x direction
1577 pady=amount - add padding in y direction
1578 side=TOP or BOTTOM or LEFT or RIGHT - where to add this widget.
1579 """
1580 self.tk.call(
1581 ('pack', 'configure', self._w)
1582 + self._options(cnf, kw))
1583 pack = configure = config = pack_configure
1584 def pack_forget(self):
1585 """Unmap this widget and do not use it for the packing order."""
1586 self.tk.call('pack', 'forget', self._w)
1587 forget = pack_forget
1588 def pack_info(self):
1589 """Return information about the packing options
1590 for this widget."""
1591 words = self.tk.splitlist(
1592 self.tk.call('pack', 'info', self._w))
1593 dict = {}
1594 for i in range(0, len(words), 2):
1595 key = words[i][1:]
1596 value = words[i+1]
1597 if value[:1] == '.':
1598 value = self._nametowidget(value)
1599 dict[key] = value
1600 return dict
1601 info = pack_info
1602 propagate = pack_propagate = Misc.pack_propagate
1603 slaves = pack_slaves = Misc.pack_slaves
Guido van Rossum18468821994-06-20 07:49:28 +00001604
1605class Place:
Fredrik Lundh06d28152000-08-09 18:03:12 +00001606 """Geometry manager Place.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001607
Fredrik Lundh06d28152000-08-09 18:03:12 +00001608 Base class to use the methods place_* in every widget."""
1609 def place_configure(self, cnf={}, **kw):
1610 """Place a widget in the parent widget. Use as options:
1611 in=master - master relative to which the widget is placed.
1612 x=amount - locate anchor of this widget at position x of master
1613 y=amount - locate anchor of this widget at position y of master
1614 relx=amount - locate anchor of this widget between 0.0 and 1.0
1615 relative to width of master (1.0 is right edge)
1616 rely=amount - locate anchor of this widget between 0.0 and 1.0
1617 relative to height of master (1.0 is bottom edge)
1618 anchor=NSEW (or subset) - position anchor according to given direction
1619 width=amount - width of this widget in pixel
1620 height=amount - height of this widget in pixel
1621 relwidth=amount - width of this widget between 0.0 and 1.0
1622 relative to width of master (1.0 is the same width
1623 as the master)
1624 relheight=amount - height of this widget between 0.0 and 1.0
1625 relative to height of master (1.0 is the same
1626 height as the master)
1627 bordermode="inside" or "outside" - whether to take border width of master widget
1628 into account
1629 """
1630 for k in ['in_']:
1631 if kw.has_key(k):
1632 kw[k[:-1]] = kw[k]
1633 del kw[k]
1634 self.tk.call(
1635 ('place', 'configure', self._w)
1636 + self._options(cnf, kw))
1637 place = configure = config = place_configure
1638 def place_forget(self):
1639 """Unmap this widget."""
1640 self.tk.call('place', 'forget', self._w)
1641 forget = place_forget
1642 def place_info(self):
1643 """Return information about the placing options
1644 for this widget."""
1645 words = self.tk.splitlist(
1646 self.tk.call('place', 'info', self._w))
1647 dict = {}
1648 for i in range(0, len(words), 2):
1649 key = words[i][1:]
1650 value = words[i+1]
1651 if value[:1] == '.':
1652 value = self._nametowidget(value)
1653 dict[key] = value
1654 return dict
1655 info = place_info
1656 slaves = place_slaves = Misc.place_slaves
Guido van Rossum18468821994-06-20 07:49:28 +00001657
Guido van Rossum37dcab11996-05-16 16:00:19 +00001658class Grid:
Fredrik Lundh06d28152000-08-09 18:03:12 +00001659 """Geometry manager Grid.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001660
Fredrik Lundh06d28152000-08-09 18:03:12 +00001661 Base class to use the methods grid_* in every widget."""
1662 # Thanks to Masazumi Yoshikawa (yosikawa@isi.edu)
1663 def grid_configure(self, cnf={}, **kw):
1664 """Position a widget in the parent widget in a grid. Use as options:
1665 column=number - use cell identified with given column (starting with 0)
1666 columnspan=number - this widget will span several columns
1667 in=master - use master to contain this widget
1668 ipadx=amount - add internal padding in x direction
1669 ipady=amount - add internal padding in y direction
1670 padx=amount - add padding in x direction
1671 pady=amount - add padding in y direction
1672 row=number - use cell identified with given row (starting with 0)
1673 rowspan=number - this widget will span several rows
1674 sticky=NSEW - if cell is larger on which sides will this
1675 widget stick to the cell boundary
1676 """
1677 self.tk.call(
1678 ('grid', 'configure', self._w)
1679 + self._options(cnf, kw))
1680 grid = configure = config = grid_configure
1681 bbox = grid_bbox = Misc.grid_bbox
1682 columnconfigure = grid_columnconfigure = Misc.grid_columnconfigure
1683 def grid_forget(self):
1684 """Unmap this widget."""
1685 self.tk.call('grid', 'forget', self._w)
1686 forget = grid_forget
1687 def grid_remove(self):
1688 """Unmap this widget but remember the grid options."""
1689 self.tk.call('grid', 'remove', self._w)
1690 def grid_info(self):
1691 """Return information about the options
1692 for positioning this widget in a grid."""
1693 words = self.tk.splitlist(
1694 self.tk.call('grid', 'info', self._w))
1695 dict = {}
1696 for i in range(0, len(words), 2):
1697 key = words[i][1:]
1698 value = words[i+1]
1699 if value[:1] == '.':
1700 value = self._nametowidget(value)
1701 dict[key] = value
1702 return dict
1703 info = grid_info
1704 def grid_location(self, x, y):
1705 """Return a tuple of column and row which identify the cell
1706 at which the pixel at position X and Y inside the master
1707 widget is located."""
1708 return self._getints(
1709 self.tk.call(
1710 'grid', 'location', self._w, x, y)) or None
1711 location = grid_location
1712 propagate = grid_propagate = Misc.grid_propagate
1713 rowconfigure = grid_rowconfigure = Misc.grid_rowconfigure
1714 size = grid_size = Misc.grid_size
1715 slaves = grid_slaves = Misc.grid_slaves
Guido van Rossum37dcab11996-05-16 16:00:19 +00001716
Guido van Rossum368e06b1997-11-07 20:38:49 +00001717class BaseWidget(Misc):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001718 """Internal class."""
1719 def _setup(self, master, cnf):
1720 """Internal function. Sets up information about children."""
1721 if _support_default_root:
1722 global _default_root
1723 if not master:
1724 if not _default_root:
1725 _default_root = Tk()
1726 master = _default_root
1727 self.master = master
1728 self.tk = master.tk
1729 name = None
1730 if cnf.has_key('name'):
1731 name = cnf['name']
1732 del cnf['name']
1733 if not name:
1734 name = `id(self)`
1735 self._name = name
1736 if master._w=='.':
1737 self._w = '.' + name
1738 else:
1739 self._w = master._w + '.' + name
1740 self.children = {}
1741 if self.master.children.has_key(self._name):
1742 self.master.children[self._name].destroy()
1743 self.master.children[self._name] = self
1744 def __init__(self, master, widgetName, cnf={}, kw={}, extra=()):
1745 """Construct a widget with the parent widget MASTER, a name WIDGETNAME
1746 and appropriate options."""
1747 if kw:
1748 cnf = _cnfmerge((cnf, kw))
1749 self.widgetName = widgetName
1750 BaseWidget._setup(self, master, cnf)
1751 classes = []
1752 for k in cnf.keys():
1753 if type(k) is ClassType:
1754 classes.append((k, cnf[k]))
1755 del cnf[k]
1756 self.tk.call(
1757 (widgetName, self._w) + extra + self._options(cnf))
1758 for k, v in classes:
1759 k.configure(self, v)
1760 def destroy(self):
1761 """Destroy this and all descendants widgets."""
1762 for c in self.children.values(): c.destroy()
1763 if self.master.children.has_key(self._name):
1764 del self.master.children[self._name]
1765 self.tk.call('destroy', self._w)
1766 Misc.destroy(self)
1767 def _do(self, name, args=()):
1768 # XXX Obsolete -- better use self.tk.call directly!
1769 return self.tk.call((self._w, name) + args)
Guido van Rossum18468821994-06-20 07:49:28 +00001770
Guido van Rossum368e06b1997-11-07 20:38:49 +00001771class Widget(BaseWidget, Pack, Place, Grid):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001772 """Internal class.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001773
Fredrik Lundh06d28152000-08-09 18:03:12 +00001774 Base class for a widget which can be positioned with the geometry managers
1775 Pack, Place or Grid."""
1776 pass
Guido van Rossum368e06b1997-11-07 20:38:49 +00001777
1778class Toplevel(BaseWidget, Wm):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001779 """Toplevel widget, e.g. for dialogs."""
1780 def __init__(self, master=None, cnf={}, **kw):
1781 """Construct a toplevel widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001782
Fredrik Lundh06d28152000-08-09 18:03:12 +00001783 Valid resource names: background, bd, bg, borderwidth, class,
1784 colormap, container, cursor, height, highlightbackground,
1785 highlightcolor, highlightthickness, menu, relief, screen, takefocus,
1786 use, visual, width."""
1787 if kw:
1788 cnf = _cnfmerge((cnf, kw))
1789 extra = ()
1790 for wmkey in ['screen', 'class_', 'class', 'visual',
1791 'colormap']:
1792 if cnf.has_key(wmkey):
1793 val = cnf[wmkey]
1794 # TBD: a hack needed because some keys
1795 # are not valid as keyword arguments
1796 if wmkey[-1] == '_': opt = '-'+wmkey[:-1]
1797 else: opt = '-'+wmkey
1798 extra = extra + (opt, val)
1799 del cnf[wmkey]
1800 BaseWidget.__init__(self, master, 'toplevel', cnf, {}, extra)
1801 root = self._root()
1802 self.iconname(root.iconname())
1803 self.title(root.title())
1804 self.protocol("WM_DELETE_WINDOW", self.destroy)
Guido van Rossum18468821994-06-20 07:49:28 +00001805
1806class Button(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001807 """Button widget."""
1808 def __init__(self, master=None, cnf={}, **kw):
1809 """Construct a button widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001810
Fredrik Lundh06d28152000-08-09 18:03:12 +00001811 Valid resource names: activebackground, activeforeground, anchor,
1812 background, bd, bg, bitmap, borderwidth, command, cursor, default,
1813 disabledforeground, fg, font, foreground, height,
1814 highlightbackground, highlightcolor, highlightthickness, image,
1815 justify, padx, pady, relief, state, takefocus, text, textvariable,
1816 underline, width, wraplength."""
1817 Widget.__init__(self, master, 'button', cnf, kw)
1818 def tkButtonEnter(self, *dummy):
1819 self.tk.call('tkButtonEnter', self._w)
1820 def tkButtonLeave(self, *dummy):
1821 self.tk.call('tkButtonLeave', self._w)
1822 def tkButtonDown(self, *dummy):
1823 self.tk.call('tkButtonDown', self._w)
1824 def tkButtonUp(self, *dummy):
1825 self.tk.call('tkButtonUp', self._w)
1826 def tkButtonInvoke(self, *dummy):
1827 self.tk.call('tkButtonInvoke', self._w)
1828 def flash(self):
1829 self.tk.call(self._w, 'flash')
1830 def invoke(self):
1831 return self.tk.call(self._w, 'invoke')
Guido van Rossum18468821994-06-20 07:49:28 +00001832
1833# Indices:
Guido van Rossum35f67fb1995-08-04 03:50:29 +00001834# XXX I don't like these -- take them away
Guido van Rossum18468821994-06-20 07:49:28 +00001835def AtEnd():
Fredrik Lundh06d28152000-08-09 18:03:12 +00001836 return 'end'
Guido van Rossum1e9e4001994-06-20 09:09:51 +00001837def AtInsert(*args):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001838 s = 'insert'
1839 for a in args:
1840 if a: s = s + (' ' + a)
1841 return s
Guido van Rossum18468821994-06-20 07:49:28 +00001842def AtSelFirst():
Fredrik Lundh06d28152000-08-09 18:03:12 +00001843 return 'sel.first'
Guido van Rossum18468821994-06-20 07:49:28 +00001844def AtSelLast():
Fredrik Lundh06d28152000-08-09 18:03:12 +00001845 return 'sel.last'
Guido van Rossum18468821994-06-20 07:49:28 +00001846def At(x, y=None):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001847 if y is None:
1848 return '@' + `x`
1849 else:
1850 return '@' + `x` + ',' + `y`
Guido van Rossum18468821994-06-20 07:49:28 +00001851
1852class Canvas(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001853 """Canvas widget to display graphical elements like lines or text."""
1854 def __init__(self, master=None, cnf={}, **kw):
1855 """Construct a canvas widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001856
Fredrik Lundh06d28152000-08-09 18:03:12 +00001857 Valid resource names: background, bd, bg, borderwidth, closeenough,
1858 confine, cursor, height, highlightbackground, highlightcolor,
1859 highlightthickness, insertbackground, insertborderwidth,
1860 insertofftime, insertontime, insertwidth, offset, relief,
1861 scrollregion, selectbackground, selectborderwidth, selectforeground,
1862 state, takefocus, width, xscrollcommand, xscrollincrement,
1863 yscrollcommand, yscrollincrement."""
1864 Widget.__init__(self, master, 'canvas', cnf, kw)
1865 def addtag(self, *args):
1866 """Internal function."""
1867 self.tk.call((self._w, 'addtag') + args)
1868 def addtag_above(self, newtag, tagOrId):
1869 """Add tag NEWTAG to all items above TAGORID."""
1870 self.addtag(newtag, 'above', tagOrId)
1871 def addtag_all(self, newtag):
1872 """Add tag NEWTAG to all items."""
1873 self.addtag(newtag, 'all')
1874 def addtag_below(self, newtag, tagOrId):
1875 """Add tag NEWTAG to all items below TAGORID."""
1876 self.addtag(newtag, 'below', tagOrId)
1877 def addtag_closest(self, newtag, x, y, halo=None, start=None):
1878 """Add tag NEWTAG to item which is closest to pixel at X, Y.
1879 If several match take the top-most.
1880 All items closer than HALO are considered overlapping (all are
1881 closests). If START is specified the next below this tag is taken."""
1882 self.addtag(newtag, 'closest', x, y, halo, start)
1883 def addtag_enclosed(self, newtag, x1, y1, x2, y2):
1884 """Add tag NEWTAG to all items in the rectangle defined
1885 by X1,Y1,X2,Y2."""
1886 self.addtag(newtag, 'enclosed', x1, y1, x2, y2)
1887 def addtag_overlapping(self, newtag, x1, y1, x2, y2):
1888 """Add tag NEWTAG to all items which overlap the rectangle
1889 defined by X1,Y1,X2,Y2."""
1890 self.addtag(newtag, 'overlapping', x1, y1, x2, y2)
1891 def addtag_withtag(self, newtag, tagOrId):
1892 """Add tag NEWTAG to all items with TAGORID."""
1893 self.addtag(newtag, 'withtag', tagOrId)
1894 def bbox(self, *args):
1895 """Return a tuple of X1,Y1,X2,Y2 coordinates for a rectangle
1896 which encloses all items with tags specified as arguments."""
1897 return self._getints(
1898 self.tk.call((self._w, 'bbox') + args)) or None
1899 def tag_unbind(self, tagOrId, sequence, funcid=None):
1900 """Unbind for all items with TAGORID for event SEQUENCE the
1901 function identified with FUNCID."""
1902 self.tk.call(self._w, 'bind', tagOrId, sequence, '')
1903 if funcid:
1904 self.deletecommand(funcid)
1905 def tag_bind(self, tagOrId, sequence=None, func=None, add=None):
1906 """Bind to all items with TAGORID at event SEQUENCE a call to function FUNC.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001907
Fredrik Lundh06d28152000-08-09 18:03:12 +00001908 An additional boolean parameter ADD specifies whether FUNC will be
1909 called additionally to the other bound function or whether it will
1910 replace the previous function. See bind for the return value."""
1911 return self._bind((self._w, 'bind', tagOrId),
1912 sequence, func, add)
1913 def canvasx(self, screenx, gridspacing=None):
1914 """Return the canvas x coordinate of pixel position SCREENX rounded
1915 to nearest multiple of GRIDSPACING units."""
1916 return getdouble(self.tk.call(
1917 self._w, 'canvasx', screenx, gridspacing))
1918 def canvasy(self, screeny, gridspacing=None):
1919 """Return the canvas y coordinate of pixel position SCREENY rounded
1920 to nearest multiple of GRIDSPACING units."""
1921 return getdouble(self.tk.call(
1922 self._w, 'canvasy', screeny, gridspacing))
1923 def coords(self, *args):
1924 """Return a list of coordinates for the item given in ARGS."""
1925 # XXX Should use _flatten on args
1926 return map(getdouble,
Guido van Rossum0bd54331998-05-19 21:18:13 +00001927 self.tk.splitlist(
Fredrik Lundh06d28152000-08-09 18:03:12 +00001928 self.tk.call((self._w, 'coords') + args)))
1929 def _create(self, itemType, args, kw): # Args: (val, val, ..., cnf={})
1930 """Internal function."""
1931 args = _flatten(args)
1932 cnf = args[-1]
1933 if type(cnf) in (DictionaryType, TupleType):
1934 args = args[:-1]
1935 else:
1936 cnf = {}
1937 return getint(apply(
1938 self.tk.call,
1939 (self._w, 'create', itemType)
1940 + args + self._options(cnf, kw)))
1941 def create_arc(self, *args, **kw):
1942 """Create arc shaped region with coordinates x1,y1,x2,y2."""
1943 return self._create('arc', args, kw)
1944 def create_bitmap(self, *args, **kw):
1945 """Create bitmap with coordinates x1,y1."""
1946 return self._create('bitmap', args, kw)
1947 def create_image(self, *args, **kw):
1948 """Create image item with coordinates x1,y1."""
1949 return self._create('image', args, kw)
1950 def create_line(self, *args, **kw):
1951 """Create line with coordinates x1,y1,...,xn,yn."""
1952 return self._create('line', args, kw)
1953 def create_oval(self, *args, **kw):
1954 """Create oval with coordinates x1,y1,x2,y2."""
1955 return self._create('oval', args, kw)
1956 def create_polygon(self, *args, **kw):
1957 """Create polygon with coordinates x1,y1,...,xn,yn."""
1958 return self._create('polygon', args, kw)
1959 def create_rectangle(self, *args, **kw):
1960 """Create rectangle with coordinates x1,y1,x2,y2."""
1961 return self._create('rectangle', args, kw)
1962 def create_text(self, *args, **kw):
1963 """Create text with coordinates x1,y1."""
1964 return self._create('text', args, kw)
1965 def create_window(self, *args, **kw):
1966 """Create window with coordinates x1,y1,x2,y2."""
1967 return self._create('window', args, kw)
1968 def dchars(self, *args):
1969 """Delete characters of text items identified by tag or id in ARGS (possibly
1970 several times) from FIRST to LAST character (including)."""
1971 self.tk.call((self._w, 'dchars') + args)
1972 def delete(self, *args):
1973 """Delete items identified by all tag or ids contained in ARGS."""
1974 self.tk.call((self._w, 'delete') + args)
1975 def dtag(self, *args):
1976 """Delete tag or id given as last arguments in ARGS from items
1977 identified by first argument in ARGS."""
1978 self.tk.call((self._w, 'dtag') + args)
1979 def find(self, *args):
1980 """Internal function."""
1981 return self._getints(
1982 self.tk.call((self._w, 'find') + args)) or ()
1983 def find_above(self, tagOrId):
1984 """Return items above TAGORID."""
1985 return self.find('above', tagOrId)
1986 def find_all(self):
1987 """Return all items."""
1988 return self.find('all')
1989 def find_below(self, tagOrId):
1990 """Return all items below TAGORID."""
1991 return self.find('below', tagOrId)
1992 def find_closest(self, x, y, halo=None, start=None):
1993 """Return item which is closest to pixel at X, Y.
1994 If several match take the top-most.
1995 All items closer than HALO are considered overlapping (all are
1996 closests). If START is specified the next below this tag is taken."""
1997 return self.find('closest', x, y, halo, start)
1998 def find_enclosed(self, x1, y1, x2, y2):
1999 """Return all items in rectangle defined
2000 by X1,Y1,X2,Y2."""
2001 return self.find('enclosed', x1, y1, x2, y2)
2002 def find_overlapping(self, x1, y1, x2, y2):
2003 """Return all items which overlap the rectangle
2004 defined by X1,Y1,X2,Y2."""
2005 return self.find('overlapping', x1, y1, x2, y2)
2006 def find_withtag(self, tagOrId):
2007 """Return all items with TAGORID."""
2008 return self.find('withtag', tagOrId)
2009 def focus(self, *args):
2010 """Set focus to the first item specified in ARGS."""
2011 return self.tk.call((self._w, 'focus') + args)
2012 def gettags(self, *args):
2013 """Return tags associated with the first item specified in ARGS."""
2014 return self.tk.splitlist(
2015 self.tk.call((self._w, 'gettags') + args))
2016 def icursor(self, *args):
2017 """Set cursor at position POS in the item identified by TAGORID.
2018 In ARGS TAGORID must be first."""
2019 self.tk.call((self._w, 'icursor') + args)
2020 def index(self, *args):
2021 """Return position of cursor as integer in item specified in ARGS."""
2022 return getint(self.tk.call((self._w, 'index') + args))
2023 def insert(self, *args):
2024 """Insert TEXT in item TAGORID at position POS. ARGS must
2025 be TAGORID POS TEXT."""
2026 self.tk.call((self._w, 'insert') + args)
2027 def itemcget(self, tagOrId, option):
2028 """Return the resource value for an OPTION for item TAGORID."""
2029 return self.tk.call(
2030 (self._w, 'itemcget') + (tagOrId, '-'+option))
2031 def itemconfigure(self, tagOrId, cnf=None, **kw):
2032 """Configure resources of an item TAGORID.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002033
Fredrik Lundh06d28152000-08-09 18:03:12 +00002034 The values for resources are specified as keyword
2035 arguments. To get an overview about
2036 the allowed keyword arguments call the method without arguments.
2037 """
2038 if cnf is None and not kw:
2039 cnf = {}
2040 for x in self.tk.split(
2041 self.tk.call(self._w,
2042 'itemconfigure', tagOrId)):
2043 cnf[x[0][1:]] = (x[0][1:],) + x[1:]
2044 return cnf
2045 if type(cnf) == StringType and not kw:
2046 x = self.tk.split(self.tk.call(
2047 self._w, 'itemconfigure', tagOrId, '-'+cnf))
2048 return (x[0][1:],) + x[1:]
2049 self.tk.call((self._w, 'itemconfigure', tagOrId) +
2050 self._options(cnf, kw))
2051 itemconfig = itemconfigure
2052 # lower, tkraise/lift hide Misc.lower, Misc.tkraise/lift,
2053 # so the preferred name for them is tag_lower, tag_raise
2054 # (similar to tag_bind, and similar to the Text widget);
2055 # unfortunately can't delete the old ones yet (maybe in 1.6)
2056 def tag_lower(self, *args):
2057 """Lower an item TAGORID given in ARGS
2058 (optional below another item)."""
2059 self.tk.call((self._w, 'lower') + args)
2060 lower = tag_lower
2061 def move(self, *args):
2062 """Move an item TAGORID given in ARGS."""
2063 self.tk.call((self._w, 'move') + args)
2064 def postscript(self, cnf={}, **kw):
2065 """Print the contents of the canvas to a postscript
2066 file. Valid options: colormap, colormode, file, fontmap,
2067 height, pageanchor, pageheight, pagewidth, pagex, pagey,
2068 rotate, witdh, x, y."""
2069 return self.tk.call((self._w, 'postscript') +
2070 self._options(cnf, kw))
2071 def tag_raise(self, *args):
2072 """Raise an item TAGORID given in ARGS
2073 (optional above another item)."""
2074 self.tk.call((self._w, 'raise') + args)
2075 lift = tkraise = tag_raise
2076 def scale(self, *args):
2077 """Scale item TAGORID with XORIGIN, YORIGIN, XSCALE, YSCALE."""
2078 self.tk.call((self._w, 'scale') + args)
2079 def scan_mark(self, x, y):
2080 """Remember the current X, Y coordinates."""
2081 self.tk.call(self._w, 'scan', 'mark', x, y)
2082 def scan_dragto(self, x, y):
2083 """Adjust the view of the canvas to 10 times the
2084 difference between X and Y and the coordinates given in
2085 scan_mark."""
2086 self.tk.call(self._w, 'scan', 'dragto', x, y)
2087 def select_adjust(self, tagOrId, index):
2088 """Adjust the end of the selection near the cursor of an item TAGORID to index."""
2089 self.tk.call(self._w, 'select', 'adjust', tagOrId, index)
2090 def select_clear(self):
2091 """Clear the selection if it is in this widget."""
2092 self.tk.call(self._w, 'select', 'clear')
2093 def select_from(self, tagOrId, index):
2094 """Set the fixed end of a selection in item TAGORID to INDEX."""
2095 self.tk.call(self._w, 'select', 'from', tagOrId, index)
2096 def select_item(self):
2097 """Return the item which has the selection."""
2098 self.tk.call(self._w, 'select', 'item')
2099 def select_to(self, tagOrId, index):
2100 """Set the variable end of a selection in item TAGORID to INDEX."""
2101 self.tk.call(self._w, 'select', 'to', tagOrId, index)
2102 def type(self, tagOrId):
2103 """Return the type of the item TAGORID."""
2104 return self.tk.call(self._w, 'type', tagOrId) or None
2105 def xview(self, *args):
2106 """Query and change horizontal position of the view."""
2107 if not args:
2108 return self._getdoubles(self.tk.call(self._w, 'xview'))
2109 self.tk.call((self._w, 'xview') + args)
2110 def xview_moveto(self, fraction):
2111 """Adjusts the view in the window so that FRACTION of the
2112 total width of the canvas is off-screen to the left."""
2113 self.tk.call(self._w, 'xview', 'moveto', fraction)
2114 def xview_scroll(self, number, what):
2115 """Shift the x-view according to NUMBER which is measured in "units" or "pages" (WHAT)."""
2116 self.tk.call(self._w, 'xview', 'scroll', number, what)
2117 def yview(self, *args):
2118 """Query and change vertical position of the view."""
2119 if not args:
2120 return self._getdoubles(self.tk.call(self._w, 'yview'))
2121 self.tk.call((self._w, 'yview') + args)
2122 def yview_moveto(self, fraction):
2123 """Adjusts the view in the window so that FRACTION of the
2124 total height of the canvas is off-screen to the top."""
2125 self.tk.call(self._w, 'yview', 'moveto', fraction)
2126 def yview_scroll(self, number, what):
2127 """Shift the y-view according to NUMBER which is measured in "units" or "pages" (WHAT)."""
2128 self.tk.call(self._w, 'yview', 'scroll', number, what)
Guido van Rossum18468821994-06-20 07:49:28 +00002129
2130class Checkbutton(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002131 """Checkbutton widget which is either in on- or off-state."""
2132 def __init__(self, master=None, cnf={}, **kw):
2133 """Construct a checkbutton widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002134
Fredrik Lundh06d28152000-08-09 18:03:12 +00002135 Valid resource names: activebackground, activeforeground, anchor,
2136 background, bd, bg, bitmap, borderwidth, command, cursor,
2137 disabledforeground, fg, font, foreground, height,
2138 highlightbackground, highlightcolor, highlightthickness, image,
2139 indicatoron, justify, offvalue, onvalue, padx, pady, relief,
2140 selectcolor, selectimage, state, takefocus, text, textvariable,
2141 underline, variable, width, wraplength."""
2142 Widget.__init__(self, master, 'checkbutton', cnf, kw)
2143 def deselect(self):
2144 """Put the button in off-state."""
2145 self.tk.call(self._w, 'deselect')
2146 def flash(self):
2147 """Flash the button."""
2148 self.tk.call(self._w, 'flash')
2149 def invoke(self):
2150 """Toggle the button and invoke a command if given as resource."""
2151 return self.tk.call(self._w, 'invoke')
2152 def select(self):
2153 """Put the button in on-state."""
2154 self.tk.call(self._w, 'select')
2155 def toggle(self):
2156 """Toggle the button."""
2157 self.tk.call(self._w, 'toggle')
Guido van Rossum18468821994-06-20 07:49:28 +00002158
2159class Entry(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002160 """Entry widget which allows to display simple text."""
2161 def __init__(self, master=None, cnf={}, **kw):
2162 """Construct an entry widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002163
Fredrik Lundh06d28152000-08-09 18:03:12 +00002164 Valid resource names: background, bd, bg, borderwidth, cursor,
2165 exportselection, fg, font, foreground, highlightbackground,
2166 highlightcolor, highlightthickness, insertbackground,
2167 insertborderwidth, insertofftime, insertontime, insertwidth,
2168 invalidcommand, invcmd, justify, relief, selectbackground,
2169 selectborderwidth, selectforeground, show, state, takefocus,
2170 textvariable, validate, validatecommand, vcmd, width,
2171 xscrollcommand."""
2172 Widget.__init__(self, master, 'entry', cnf, kw)
2173 def delete(self, first, last=None):
2174 """Delete text from FIRST to LAST (not included)."""
2175 self.tk.call(self._w, 'delete', first, last)
2176 def get(self):
2177 """Return the text."""
2178 return self.tk.call(self._w, 'get')
2179 def icursor(self, index):
2180 """Insert cursor at INDEX."""
2181 self.tk.call(self._w, 'icursor', index)
2182 def index(self, index):
2183 """Return position of cursor."""
2184 return getint(self.tk.call(
2185 self._w, 'index', index))
2186 def insert(self, index, string):
2187 """Insert STRING at INDEX."""
2188 self.tk.call(self._w, 'insert', index, string)
2189 def scan_mark(self, x):
2190 """Remember the current X, Y coordinates."""
2191 self.tk.call(self._w, 'scan', 'mark', x)
2192 def scan_dragto(self, x):
2193 """Adjust the view of the canvas to 10 times the
2194 difference between X and Y and the coordinates given in
2195 scan_mark."""
2196 self.tk.call(self._w, 'scan', 'dragto', x)
2197 def selection_adjust(self, index):
2198 """Adjust the end of the selection near the cursor to INDEX."""
2199 self.tk.call(self._w, 'selection', 'adjust', index)
2200 select_adjust = selection_adjust
2201 def selection_clear(self):
2202 """Clear the selection if it is in this widget."""
2203 self.tk.call(self._w, 'selection', 'clear')
2204 select_clear = selection_clear
2205 def selection_from(self, index):
2206 """Set the fixed end of a selection to INDEX."""
2207 self.tk.call(self._w, 'selection', 'from', index)
2208 select_from = selection_from
2209 def selection_present(self):
2210 """Return whether the widget has the selection."""
2211 return self.tk.getboolean(
2212 self.tk.call(self._w, 'selection', 'present'))
2213 select_present = selection_present
2214 def selection_range(self, start, end):
2215 """Set the selection from START to END (not included)."""
2216 self.tk.call(self._w, 'selection', 'range', start, end)
2217 select_range = selection_range
2218 def selection_to(self, index):
2219 """Set the variable end of a selection to INDEX."""
2220 self.tk.call(self._w, 'selection', 'to', index)
2221 select_to = selection_to
2222 def xview(self, index):
2223 """Query and change horizontal position of the view."""
2224 self.tk.call(self._w, 'xview', index)
2225 def xview_moveto(self, fraction):
2226 """Adjust the view in the window so that FRACTION of the
2227 total width of the entry is off-screen to the left."""
2228 self.tk.call(self._w, 'xview', 'moveto', fraction)
2229 def xview_scroll(self, number, what):
2230 """Shift the x-view according to NUMBER which is measured in "units" or "pages" (WHAT)."""
2231 self.tk.call(self._w, 'xview', 'scroll', number, what)
Guido van Rossum18468821994-06-20 07:49:28 +00002232
2233class Frame(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002234 """Frame widget which may contain other widgets and can have a 3D border."""
2235 def __init__(self, master=None, cnf={}, **kw):
2236 """Construct a frame widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002237
Fredrik Lundh06d28152000-08-09 18:03:12 +00002238 Valid resource names: background, bd, bg, borderwidth, class,
2239 colormap, container, cursor, height, highlightbackground,
2240 highlightcolor, highlightthickness, relief, takefocus, visual, width."""
2241 cnf = _cnfmerge((cnf, kw))
2242 extra = ()
2243 if cnf.has_key('class_'):
2244 extra = ('-class', cnf['class_'])
2245 del cnf['class_']
2246 elif cnf.has_key('class'):
2247 extra = ('-class', cnf['class'])
2248 del cnf['class']
2249 Widget.__init__(self, master, 'frame', cnf, {}, extra)
Guido van Rossum18468821994-06-20 07:49:28 +00002250
2251class Label(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002252 """Label widget which can display text and bitmaps."""
2253 def __init__(self, master=None, cnf={}, **kw):
2254 """Construct a label widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002255
Fredrik Lundh06d28152000-08-09 18:03:12 +00002256 Valid resource names: anchor, background, bd, bg, bitmap,
2257 borderwidth, cursor, fg, font, foreground, height,
2258 highlightbackground, highlightcolor, highlightthickness, image,
2259 justify, padx, pady, relief, takefocus, text, textvariable,
2260 underline, width, wraplength."""
2261 Widget.__init__(self, master, 'label', cnf, kw)
Guido van Rossum761c5ab1995-07-14 15:29:10 +00002262
Guido van Rossum18468821994-06-20 07:49:28 +00002263class Listbox(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002264 """Listbox widget which can display a list of strings."""
2265 def __init__(self, master=None, cnf={}, **kw):
2266 """Construct a listbox widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002267
Fredrik Lundh06d28152000-08-09 18:03:12 +00002268 Valid resource names: background, bd, bg, borderwidth, cursor,
2269 exportselection, fg, font, foreground, height, highlightbackground,
2270 highlightcolor, highlightthickness, relief, selectbackground,
2271 selectborderwidth, selectforeground, selectmode, setgrid, takefocus,
2272 width, xscrollcommand, yscrollcommand, listvariable."""
2273 Widget.__init__(self, master, 'listbox', cnf, kw)
2274 def activate(self, index):
2275 """Activate item identified by INDEX."""
2276 self.tk.call(self._w, 'activate', index)
2277 def bbox(self, *args):
2278 """Return a tuple of X1,Y1,X2,Y2 coordinates for a rectangle
2279 which encloses the item identified by index in ARGS."""
2280 return self._getints(
2281 self.tk.call((self._w, 'bbox') + args)) or None
2282 def curselection(self):
2283 """Return list of indices of currently selected item."""
2284 # XXX Ought to apply self._getints()...
2285 return self.tk.splitlist(self.tk.call(
2286 self._w, 'curselection'))
2287 def delete(self, first, last=None):
2288 """Delete items from FIRST to LAST (not included)."""
2289 self.tk.call(self._w, 'delete', first, last)
2290 def get(self, first, last=None):
2291 """Get list of items from FIRST to LAST (not included)."""
2292 if last:
2293 return self.tk.splitlist(self.tk.call(
2294 self._w, 'get', first, last))
2295 else:
2296 return self.tk.call(self._w, 'get', first)
2297 def index(self, index):
2298 """Return index of item identified with INDEX."""
2299 i = self.tk.call(self._w, 'index', index)
2300 if i == 'none': return None
2301 return getint(i)
2302 def insert(self, index, *elements):
2303 """Insert ELEMENTS at INDEX."""
2304 self.tk.call((self._w, 'insert', index) + elements)
2305 def nearest(self, y):
2306 """Get index of item which is nearest to y coordinate Y."""
2307 return getint(self.tk.call(
2308 self._w, 'nearest', y))
2309 def scan_mark(self, x, y):
2310 """Remember the current X, Y coordinates."""
2311 self.tk.call(self._w, 'scan', 'mark', x, y)
2312 def scan_dragto(self, x, y):
2313 """Adjust the view of the listbox to 10 times the
2314 difference between X and Y and the coordinates given in
2315 scan_mark."""
2316 self.tk.call(self._w, 'scan', 'dragto', x, y)
2317 def see(self, index):
2318 """Scroll such that INDEX is visible."""
2319 self.tk.call(self._w, 'see', index)
2320 def selection_anchor(self, index):
2321 """Set the fixed end oft the selection to INDEX."""
2322 self.tk.call(self._w, 'selection', 'anchor', index)
2323 select_anchor = selection_anchor
2324 def selection_clear(self, first, last=None):
2325 """Clear the selection from FIRST to LAST (not included)."""
2326 self.tk.call(self._w,
2327 'selection', 'clear', first, last)
2328 select_clear = selection_clear
2329 def selection_includes(self, index):
2330 """Return 1 if INDEX is part of the selection."""
2331 return self.tk.getboolean(self.tk.call(
2332 self._w, 'selection', 'includes', index))
2333 select_includes = selection_includes
2334 def selection_set(self, first, last=None):
2335 """Set the selection from FIRST to LAST (not included) without
2336 changing the currently selected elements."""
2337 self.tk.call(self._w, 'selection', 'set', first, last)
2338 select_set = selection_set
2339 def size(self):
2340 """Return the number of elements in the listbox."""
2341 return getint(self.tk.call(self._w, 'size'))
2342 def xview(self, *what):
2343 """Query and change horizontal position of the view."""
2344 if not what:
2345 return self._getdoubles(self.tk.call(self._w, 'xview'))
2346 self.tk.call((self._w, 'xview') + what)
2347 def xview_moveto(self, fraction):
2348 """Adjust the view in the window so that FRACTION of the
2349 total width of the entry is off-screen to the left."""
2350 self.tk.call(self._w, 'xview', 'moveto', fraction)
2351 def xview_scroll(self, number, what):
2352 """Shift the x-view according to NUMBER which is measured in "units" or "pages" (WHAT)."""
2353 self.tk.call(self._w, 'xview', 'scroll', number, what)
2354 def yview(self, *what):
2355 """Query and change vertical position of the view."""
2356 if not what:
2357 return self._getdoubles(self.tk.call(self._w, 'yview'))
2358 self.tk.call((self._w, 'yview') + what)
2359 def yview_moveto(self, fraction):
2360 """Adjust the view in the window so that FRACTION of the
2361 total width of the entry is off-screen to the top."""
2362 self.tk.call(self._w, 'yview', 'moveto', fraction)
2363 def yview_scroll(self, number, what):
2364 """Shift the y-view according to NUMBER which is measured in "units" or "pages" (WHAT)."""
2365 self.tk.call(self._w, 'yview', 'scroll', number, what)
Guido van Rossuma0adb922001-09-01 18:29:55 +00002366 def itemconfigure(self, index, cnf=None, **kw):
2367 """Configure resources of an item.
2368
2369 The values for resources are specified as keyword arguments.
2370 To get an overview about the allowed keyword arguments
2371 call the method without arguments.
2372 Valid resource names: background, bg, foreground, fg,
2373 selectbackground, selectforeground."""
2374 if cnf is None and not kw:
2375 cnf = {}
2376 for x in self.tk.split(
2377 self.tk.call(self._w, 'itemconfigure', index)):
2378 cnf[x[0][1:]] = (x[0][1:],) + x[1:]
2379 return cnf
2380 if type(cnf) == StringType and not kw:
2381 x = self.tk.split(self.tk.call(
2382 self._w, 'itemconfigure', index, '-'+cnf))
2383 return (x[0][1:],) + x[1:]
2384 self.tk.call((self._w, 'itemconfigure', index) +
2385 self._options(cnf, kw))
2386 itemconfig = itemconfigure
Guido van Rossum18468821994-06-20 07:49:28 +00002387
2388class Menu(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002389 """Menu widget which allows to display menu bars, pull-down menus and pop-up menus."""
2390 def __init__(self, master=None, cnf={}, **kw):
2391 """Construct menu widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002392
Fredrik Lundh06d28152000-08-09 18:03:12 +00002393 Valid resource names: activebackground, activeborderwidth,
2394 activeforeground, background, bd, bg, borderwidth, cursor,
2395 disabledforeground, fg, font, foreground, postcommand, relief,
2396 selectcolor, takefocus, tearoff, tearoffcommand, title, type."""
2397 Widget.__init__(self, master, 'menu', cnf, kw)
2398 def tk_bindForTraversal(self):
2399 pass # obsolete since Tk 4.0
2400 def tk_mbPost(self):
2401 self.tk.call('tk_mbPost', self._w)
2402 def tk_mbUnpost(self):
2403 self.tk.call('tk_mbUnpost')
2404 def tk_traverseToMenu(self, char):
2405 self.tk.call('tk_traverseToMenu', self._w, char)
2406 def tk_traverseWithinMenu(self, char):
2407 self.tk.call('tk_traverseWithinMenu', self._w, char)
2408 def tk_getMenuButtons(self):
2409 return self.tk.call('tk_getMenuButtons', self._w)
2410 def tk_nextMenu(self, count):
2411 self.tk.call('tk_nextMenu', count)
2412 def tk_nextMenuEntry(self, count):
2413 self.tk.call('tk_nextMenuEntry', count)
2414 def tk_invokeMenu(self):
2415 self.tk.call('tk_invokeMenu', self._w)
2416 def tk_firstMenu(self):
2417 self.tk.call('tk_firstMenu', self._w)
2418 def tk_mbButtonDown(self):
2419 self.tk.call('tk_mbButtonDown', self._w)
2420 def tk_popup(self, x, y, entry=""):
2421 """Post the menu at position X,Y with entry ENTRY."""
2422 self.tk.call('tk_popup', self._w, x, y, entry)
2423 def activate(self, index):
2424 """Activate entry at INDEX."""
2425 self.tk.call(self._w, 'activate', index)
2426 def add(self, itemType, cnf={}, **kw):
2427 """Internal function."""
2428 self.tk.call((self._w, 'add', itemType) +
2429 self._options(cnf, kw))
2430 def add_cascade(self, cnf={}, **kw):
2431 """Add hierarchical menu item."""
2432 self.add('cascade', cnf or kw)
2433 def add_checkbutton(self, cnf={}, **kw):
2434 """Add checkbutton menu item."""
2435 self.add('checkbutton', cnf or kw)
2436 def add_command(self, cnf={}, **kw):
2437 """Add command menu item."""
2438 self.add('command', cnf or kw)
2439 def add_radiobutton(self, cnf={}, **kw):
2440 """Addd radio menu item."""
2441 self.add('radiobutton', cnf or kw)
2442 def add_separator(self, cnf={}, **kw):
2443 """Add separator."""
2444 self.add('separator', cnf or kw)
2445 def insert(self, index, itemType, cnf={}, **kw):
2446 """Internal function."""
2447 self.tk.call((self._w, 'insert', index, itemType) +
2448 self._options(cnf, kw))
2449 def insert_cascade(self, index, cnf={}, **kw):
2450 """Add hierarchical menu item at INDEX."""
2451 self.insert(index, 'cascade', cnf or kw)
2452 def insert_checkbutton(self, index, cnf={}, **kw):
2453 """Add checkbutton menu item at INDEX."""
2454 self.insert(index, 'checkbutton', cnf or kw)
2455 def insert_command(self, index, cnf={}, **kw):
2456 """Add command menu item at INDEX."""
2457 self.insert(index, 'command', cnf or kw)
2458 def insert_radiobutton(self, index, cnf={}, **kw):
2459 """Addd radio menu item at INDEX."""
2460 self.insert(index, 'radiobutton', cnf or kw)
2461 def insert_separator(self, index, cnf={}, **kw):
2462 """Add separator at INDEX."""
2463 self.insert(index, 'separator', cnf or kw)
2464 def delete(self, index1, index2=None):
2465 """Delete menu items between INDEX1 and INDEX2 (not included)."""
2466 self.tk.call(self._w, 'delete', index1, index2)
2467 def entrycget(self, index, option):
2468 """Return the resource value of an menu item for OPTION at INDEX."""
2469 return self.tk.call(self._w, 'entrycget', index, '-' + option)
2470 def entryconfigure(self, index, cnf=None, **kw):
2471 """Configure a menu item at INDEX."""
2472 if cnf is None and not kw:
2473 cnf = {}
2474 for x in self.tk.split(self.tk.call(
2475 (self._w, 'entryconfigure', index))):
2476 cnf[x[0][1:]] = (x[0][1:],) + x[1:]
2477 return cnf
2478 if type(cnf) == StringType and not kw:
2479 x = self.tk.split(self.tk.call(
2480 (self._w, 'entryconfigure', index, '-'+cnf)))
2481 return (x[0][1:],) + x[1:]
2482 self.tk.call((self._w, 'entryconfigure', index)
2483 + self._options(cnf, kw))
2484 entryconfig = entryconfigure
2485 def index(self, index):
2486 """Return the index of a menu item identified by INDEX."""
2487 i = self.tk.call(self._w, 'index', index)
2488 if i == 'none': return None
2489 return getint(i)
2490 def invoke(self, index):
2491 """Invoke a menu item identified by INDEX and execute
2492 the associated command."""
2493 return self.tk.call(self._w, 'invoke', index)
2494 def post(self, x, y):
2495 """Display a menu at position X,Y."""
2496 self.tk.call(self._w, 'post', x, y)
2497 def type(self, index):
2498 """Return the type of the menu item at INDEX."""
2499 return self.tk.call(self._w, 'type', index)
2500 def unpost(self):
2501 """Unmap a menu."""
2502 self.tk.call(self._w, 'unpost')
2503 def yposition(self, index):
2504 """Return the y-position of the topmost pixel of the menu item at INDEX."""
2505 return getint(self.tk.call(
2506 self._w, 'yposition', index))
Guido van Rossum18468821994-06-20 07:49:28 +00002507
2508class Menubutton(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002509 """Menubutton widget, obsolete since Tk8.0."""
2510 def __init__(self, master=None, cnf={}, **kw):
2511 Widget.__init__(self, master, 'menubutton', cnf, kw)
Guido van Rossum18468821994-06-20 07:49:28 +00002512
2513class Message(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002514 """Message widget to display multiline text. Obsolete since Label does it too."""
2515 def __init__(self, master=None, cnf={}, **kw):
2516 Widget.__init__(self, master, 'message', cnf, kw)
Guido van Rossum18468821994-06-20 07:49:28 +00002517
2518class Radiobutton(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002519 """Radiobutton widget which shows only one of several buttons in on-state."""
2520 def __init__(self, master=None, cnf={}, **kw):
2521 """Construct a radiobutton widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002522
Fredrik Lundh06d28152000-08-09 18:03:12 +00002523 Valid resource names: activebackground, activeforeground, anchor,
2524 background, bd, bg, bitmap, borderwidth, command, cursor,
2525 disabledforeground, fg, font, foreground, height,
2526 highlightbackground, highlightcolor, highlightthickness, image,
2527 indicatoron, justify, padx, pady, relief, selectcolor, selectimage,
2528 state, takefocus, text, textvariable, underline, value, variable,
2529 width, wraplength."""
2530 Widget.__init__(self, master, 'radiobutton', cnf, kw)
2531 def deselect(self):
2532 """Put the button in off-state."""
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002533
Fredrik Lundh06d28152000-08-09 18:03:12 +00002534 self.tk.call(self._w, 'deselect')
2535 def flash(self):
2536 """Flash the button."""
2537 self.tk.call(self._w, 'flash')
2538 def invoke(self):
2539 """Toggle the button and invoke a command if given as resource."""
2540 return self.tk.call(self._w, 'invoke')
2541 def select(self):
2542 """Put the button in on-state."""
2543 self.tk.call(self._w, 'select')
Guido van Rossum18468821994-06-20 07:49:28 +00002544
2545class Scale(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002546 """Scale widget which can display a numerical scale."""
2547 def __init__(self, master=None, cnf={}, **kw):
2548 """Construct a scale widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002549
Fredrik Lundh06d28152000-08-09 18:03:12 +00002550 Valid resource names: activebackground, background, bigincrement, bd,
2551 bg, borderwidth, command, cursor, digits, fg, font, foreground, from,
2552 highlightbackground, highlightcolor, highlightthickness, label,
2553 length, orient, relief, repeatdelay, repeatinterval, resolution,
2554 showvalue, sliderlength, sliderrelief, state, takefocus,
2555 tickinterval, to, troughcolor, variable, width."""
2556 Widget.__init__(self, master, 'scale', cnf, kw)
2557 def get(self):
2558 """Get the current value as integer or float."""
2559 value = self.tk.call(self._w, 'get')
2560 try:
2561 return getint(value)
2562 except ValueError:
2563 return getdouble(value)
2564 def set(self, value):
2565 """Set the value to VALUE."""
2566 self.tk.call(self._w, 'set', value)
2567 def coords(self, value=None):
2568 """Return a tuple (X,Y) of the point along the centerline of the
2569 trough that corresponds to VALUE or the current value if None is
2570 given."""
2571
2572 return self._getints(self.tk.call(self._w, 'coords', value))
2573 def identify(self, x, y):
2574 """Return where the point X,Y lies. Valid return values are "slider",
2575 "though1" and "though2"."""
2576 return self.tk.call(self._w, 'identify', x, y)
Guido van Rossum18468821994-06-20 07:49:28 +00002577
2578class Scrollbar(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002579 """Scrollbar widget which displays a slider at a certain position."""
2580 def __init__(self, master=None, cnf={}, **kw):
2581 """Construct a scrollbar widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002582
Fredrik Lundh06d28152000-08-09 18:03:12 +00002583 Valid resource names: activebackground, activerelief,
2584 background, bd, bg, borderwidth, command, cursor,
2585 elementborderwidth, highlightbackground,
2586 highlightcolor, highlightthickness, jump, orient,
2587 relief, repeatdelay, repeatinterval, takefocus,
2588 troughcolor, width."""
2589 Widget.__init__(self, master, 'scrollbar', cnf, kw)
2590 def activate(self, index):
2591 """Display the element at INDEX with activebackground and activerelief.
2592 INDEX can be "arrow1","slider" or "arrow2"."""
2593 self.tk.call(self._w, 'activate', index)
2594 def delta(self, deltax, deltay):
2595 """Return the fractional change of the scrollbar setting if it
2596 would be moved by DELTAX or DELTAY pixels."""
2597 return getdouble(
2598 self.tk.call(self._w, 'delta', deltax, deltay))
2599 def fraction(self, x, y):
2600 """Return the fractional value which corresponds to a slider
2601 position of X,Y."""
2602 return getdouble(self.tk.call(self._w, 'fraction', x, y))
2603 def identify(self, x, y):
2604 """Return the element under position X,Y as one of
2605 "arrow1","slider","arrow2" or ""."""
2606 return self.tk.call(self._w, 'identify', x, y)
2607 def get(self):
2608 """Return the current fractional values (upper and lower end)
2609 of the slider position."""
2610 return self._getdoubles(self.tk.call(self._w, 'get'))
2611 def set(self, *args):
2612 """Set the fractional values of the slider position (upper and
2613 lower ends as value between 0 and 1)."""
2614 self.tk.call((self._w, 'set') + args)
Guido van Rossum18468821994-06-20 07:49:28 +00002615
2616class Text(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002617 """Text widget which can display text in various forms."""
2618 # XXX Add dump()
2619 def __init__(self, master=None, cnf={}, **kw):
2620 """Construct a text widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002621
Fredrik Lundh06d28152000-08-09 18:03:12 +00002622 Valid resource names: background, bd, bg, borderwidth, cursor,
2623 exportselection, fg, font, foreground, height,
2624 highlightbackground, highlightcolor, highlightthickness,
2625 insertbackground, insertborderwidth, insertofftime,
2626 insertontime, insertwidth, padx, pady, relief,
2627 selectbackground, selectborderwidth, selectforeground,
2628 setgrid, spacing1, spacing2, spacing3, state, tabs, takefocus,
2629 width, wrap, xscrollcommand, yscrollcommand."""
2630 Widget.__init__(self, master, 'text', cnf, kw)
2631 def bbox(self, *args):
2632 """Return a tuple of (x,y,width,height) which gives the bounding
2633 box of the visible part of the character at the index in ARGS."""
2634 return self._getints(
2635 self.tk.call((self._w, 'bbox') + args)) or None
2636 def tk_textSelectTo(self, index):
2637 self.tk.call('tk_textSelectTo', self._w, index)
2638 def tk_textBackspace(self):
2639 self.tk.call('tk_textBackspace', self._w)
2640 def tk_textIndexCloser(self, a, b, c):
2641 self.tk.call('tk_textIndexCloser', self._w, a, b, c)
2642 def tk_textResetAnchor(self, index):
2643 self.tk.call('tk_textResetAnchor', self._w, index)
2644 def compare(self, index1, op, index2):
2645 """Return whether between index INDEX1 and index INDEX2 the
2646 relation OP is satisfied. OP is one of <, <=, ==, >=, >, or !=."""
2647 return self.tk.getboolean(self.tk.call(
2648 self._w, 'compare', index1, op, index2))
2649 def debug(self, boolean=None):
2650 """Turn on the internal consistency checks of the B-Tree inside the text
2651 widget according to BOOLEAN."""
2652 return self.tk.getboolean(self.tk.call(
2653 self._w, 'debug', boolean))
2654 def delete(self, index1, index2=None):
2655 """Delete the characters between INDEX1 and INDEX2 (not included)."""
2656 self.tk.call(self._w, 'delete', index1, index2)
2657 def dlineinfo(self, index):
2658 """Return tuple (x,y,width,height,baseline) giving the bounding box
2659 and baseline position of the visible part of the line containing
2660 the character at INDEX."""
2661 return self._getints(self.tk.call(self._w, 'dlineinfo', index))
2662 def get(self, index1, index2=None):
2663 """Return the text from INDEX1 to INDEX2 (not included)."""
2664 return self.tk.call(self._w, 'get', index1, index2)
2665 # (Image commands are new in 8.0)
2666 def image_cget(self, index, option):
2667 """Return the value of OPTION of an embedded image at INDEX."""
2668 if option[:1] != "-":
2669 option = "-" + option
2670 if option[-1:] == "_":
2671 option = option[:-1]
2672 return self.tk.call(self._w, "image", "cget", index, option)
2673 def image_configure(self, index, cnf={}, **kw):
2674 """Configure an embedded image at INDEX."""
2675 if not cnf and not kw:
2676 cnf = {}
2677 for x in self.tk.split(
2678 self.tk.call(
2679 self._w, "image", "configure", index)):
2680 cnf[x[0][1:]] = (x[0][1:],) + x[1:]
2681 return cnf
2682 apply(self.tk.call,
2683 (self._w, "image", "configure", index)
2684 + self._options(cnf, kw))
2685 def image_create(self, index, cnf={}, **kw):
2686 """Create an embedded image at INDEX."""
2687 return apply(self.tk.call,
2688 (self._w, "image", "create", index)
2689 + self._options(cnf, kw))
2690 def image_names(self):
2691 """Return all names of embedded images in this widget."""
2692 return self.tk.call(self._w, "image", "names")
2693 def index(self, index):
2694 """Return the index in the form line.char for INDEX."""
2695 return self.tk.call(self._w, 'index', index)
2696 def insert(self, index, chars, *args):
2697 """Insert CHARS before the characters at INDEX. An additional
2698 tag can be given in ARGS. Additional CHARS and tags can follow in ARGS."""
2699 self.tk.call((self._w, 'insert', index, chars) + args)
2700 def mark_gravity(self, markName, direction=None):
2701 """Change the gravity of a mark MARKNAME to DIRECTION (LEFT or RIGHT).
2702 Return the current value if None is given for DIRECTION."""
2703 return self.tk.call(
2704 (self._w, 'mark', 'gravity', markName, direction))
2705 def mark_names(self):
2706 """Return all mark names."""
2707 return self.tk.splitlist(self.tk.call(
2708 self._w, 'mark', 'names'))
2709 def mark_set(self, markName, index):
2710 """Set mark MARKNAME before the character at INDEX."""
2711 self.tk.call(self._w, 'mark', 'set', markName, index)
2712 def mark_unset(self, *markNames):
2713 """Delete all marks in MARKNAMES."""
2714 self.tk.call((self._w, 'mark', 'unset') + markNames)
2715 def mark_next(self, index):
2716 """Return the name of the next mark after INDEX."""
2717 return self.tk.call(self._w, 'mark', 'next', index) or None
2718 def mark_previous(self, index):
2719 """Return the name of the previous mark before INDEX."""
2720 return self.tk.call(self._w, 'mark', 'previous', index) or None
2721 def scan_mark(self, x, y):
2722 """Remember the current X, Y coordinates."""
2723 self.tk.call(self._w, 'scan', 'mark', x, y)
2724 def scan_dragto(self, x, y):
2725 """Adjust the view of the text to 10 times the
2726 difference between X and Y and the coordinates given in
2727 scan_mark."""
2728 self.tk.call(self._w, 'scan', 'dragto', x, y)
2729 def search(self, pattern, index, stopindex=None,
2730 forwards=None, backwards=None, exact=None,
2731 regexp=None, nocase=None, count=None):
2732 """Search PATTERN beginning from INDEX until STOPINDEX.
2733 Return the index of the first character of a match or an empty string."""
2734 args = [self._w, 'search']
2735 if forwards: args.append('-forwards')
2736 if backwards: args.append('-backwards')
2737 if exact: args.append('-exact')
2738 if regexp: args.append('-regexp')
2739 if nocase: args.append('-nocase')
2740 if count: args.append('-count'); args.append(count)
2741 if pattern[0] == '-': args.append('--')
2742 args.append(pattern)
2743 args.append(index)
2744 if stopindex: args.append(stopindex)
2745 return self.tk.call(tuple(args))
2746 def see(self, index):
2747 """Scroll such that the character at INDEX is visible."""
2748 self.tk.call(self._w, 'see', index)
2749 def tag_add(self, tagName, index1, *args):
2750 """Add tag TAGNAME to all characters between INDEX1 and index2 in ARGS.
2751 Additional pairs of indices may follow in ARGS."""
2752 self.tk.call(
2753 (self._w, 'tag', 'add', tagName, index1) + args)
2754 def tag_unbind(self, tagName, sequence, funcid=None):
2755 """Unbind for all characters with TAGNAME for event SEQUENCE the
2756 function identified with FUNCID."""
2757 self.tk.call(self._w, 'tag', 'bind', tagName, sequence, '')
2758 if funcid:
2759 self.deletecommand(funcid)
2760 def tag_bind(self, tagName, sequence, func, add=None):
2761 """Bind to all characters with TAGNAME at event SEQUENCE a call to function FUNC.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002762
Fredrik Lundh06d28152000-08-09 18:03:12 +00002763 An additional boolean parameter ADD specifies whether FUNC will be
2764 called additionally to the other bound function or whether it will
2765 replace the previous function. See bind for the return value."""
2766 return self._bind((self._w, 'tag', 'bind', tagName),
2767 sequence, func, add)
2768 def tag_cget(self, tagName, option):
2769 """Return the value of OPTION for tag TAGNAME."""
2770 if option[:1] != '-':
2771 option = '-' + option
2772 if option[-1:] == '_':
2773 option = option[:-1]
2774 return self.tk.call(self._w, 'tag', 'cget', tagName, option)
2775 def tag_configure(self, tagName, cnf={}, **kw):
2776 """Configure a tag TAGNAME."""
2777 if type(cnf) == StringType:
2778 x = self.tk.split(self.tk.call(
2779 self._w, 'tag', 'configure', tagName, '-'+cnf))
2780 return (x[0][1:],) + x[1:]
2781 self.tk.call(
2782 (self._w, 'tag', 'configure', tagName)
2783 + self._options(cnf, kw))
2784 tag_config = tag_configure
2785 def tag_delete(self, *tagNames):
2786 """Delete all tags in TAGNAMES."""
2787 self.tk.call((self._w, 'tag', 'delete') + tagNames)
2788 def tag_lower(self, tagName, belowThis=None):
2789 """Change the priority of tag TAGNAME such that it is lower
2790 than the priority of BELOWTHIS."""
2791 self.tk.call(self._w, 'tag', 'lower', tagName, belowThis)
2792 def tag_names(self, index=None):
2793 """Return a list of all tag names."""
2794 return self.tk.splitlist(
2795 self.tk.call(self._w, 'tag', 'names', index))
2796 def tag_nextrange(self, tagName, index1, index2=None):
2797 """Return a list of start and end index for the first sequence of
2798 characters between INDEX1 and INDEX2 which all have tag TAGNAME.
2799 The text is searched forward from INDEX1."""
2800 return self.tk.splitlist(self.tk.call(
2801 self._w, 'tag', 'nextrange', tagName, index1, index2))
2802 def tag_prevrange(self, tagName, index1, index2=None):
2803 """Return a list of start and end index for the first sequence of
2804 characters between INDEX1 and INDEX2 which all have tag TAGNAME.
2805 The text is searched backwards from INDEX1."""
2806 return self.tk.splitlist(self.tk.call(
2807 self._w, 'tag', 'prevrange', tagName, index1, index2))
2808 def tag_raise(self, tagName, aboveThis=None):
2809 """Change the priority of tag TAGNAME such that it is higher
2810 than the priority of ABOVETHIS."""
2811 self.tk.call(
2812 self._w, 'tag', 'raise', tagName, aboveThis)
2813 def tag_ranges(self, tagName):
2814 """Return a list of ranges of text which have tag TAGNAME."""
2815 return self.tk.splitlist(self.tk.call(
2816 self._w, 'tag', 'ranges', tagName))
2817 def tag_remove(self, tagName, index1, index2=None):
2818 """Remove tag TAGNAME from all characters between INDEX1 and INDEX2."""
2819 self.tk.call(
2820 self._w, 'tag', 'remove', tagName, index1, index2)
2821 def window_cget(self, index, option):
2822 """Return the value of OPTION of an embedded window at INDEX."""
2823 if option[:1] != '-':
2824 option = '-' + option
2825 if option[-1:] == '_':
2826 option = option[:-1]
2827 return self.tk.call(self._w, 'window', 'cget', index, option)
2828 def window_configure(self, index, cnf={}, **kw):
2829 """Configure an embedded window at INDEX."""
2830 if type(cnf) == StringType:
2831 x = self.tk.split(self.tk.call(
2832 self._w, 'window', 'configure',
2833 index, '-'+cnf))
2834 return (x[0][1:],) + x[1:]
2835 self.tk.call(
2836 (self._w, 'window', 'configure', index)
2837 + self._options(cnf, kw))
2838 window_config = window_configure
2839 def window_create(self, index, cnf={}, **kw):
2840 """Create a window at INDEX."""
2841 self.tk.call(
2842 (self._w, 'window', 'create', index)
2843 + self._options(cnf, kw))
2844 def window_names(self):
2845 """Return all names of embedded windows in this widget."""
2846 return self.tk.splitlist(
2847 self.tk.call(self._w, 'window', 'names'))
2848 def xview(self, *what):
2849 """Query and change horizontal position of the view."""
2850 if not what:
2851 return self._getdoubles(self.tk.call(self._w, 'xview'))
2852 self.tk.call((self._w, 'xview') + what)
Fredrik Lundh5bd2cd62000-08-09 18:29:51 +00002853 def xview_moveto(self, fraction):
2854 """Adjusts the view in the window so that FRACTION of the
2855 total width of the canvas is off-screen to the left."""
2856 self.tk.call(self._w, 'xview', 'moveto', fraction)
2857 def xview_scroll(self, number, what):
2858 """Shift the x-view according to NUMBER which is measured
2859 in "units" or "pages" (WHAT)."""
2860 self.tk.call(self._w, 'xview', 'scroll', number, what)
Fredrik Lundh8fffa202000-08-09 18:51:01 +00002861 def yview(self, *what):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002862 """Query and change vertical position of the view."""
Fredrik Lundh8fffa202000-08-09 18:51:01 +00002863 if not what:
Fredrik Lundh06d28152000-08-09 18:03:12 +00002864 return self._getdoubles(self.tk.call(self._w, 'yview'))
Fredrik Lundh8fffa202000-08-09 18:51:01 +00002865 self.tk.call((self._w, 'yview') + what)
Fredrik Lundh5bd2cd62000-08-09 18:29:51 +00002866 def yview_moveto(self, fraction):
2867 """Adjusts the view in the window so that FRACTION of the
2868 total height of the canvas is off-screen to the top."""
2869 self.tk.call(self._w, 'yview', 'moveto', fraction)
2870 def yview_scroll(self, number, what):
2871 """Shift the y-view according to NUMBER which is measured
2872 in "units" or "pages" (WHAT)."""
2873 self.tk.call(self._w, 'yview', 'scroll', number, what)
Fredrik Lundh06d28152000-08-09 18:03:12 +00002874 def yview_pickplace(self, *what):
2875 """Obsolete function, use see."""
2876 self.tk.call((self._w, 'yview', '-pickplace') + what)
Guido van Rossum18468821994-06-20 07:49:28 +00002877
Guido van Rossum28574b51996-10-21 15:16:51 +00002878class _setit:
Fredrik Lundh06d28152000-08-09 18:03:12 +00002879 """Internal class. It wraps the command in the widget OptionMenu."""
2880 def __init__(self, var, value, callback=None):
2881 self.__value = value
2882 self.__var = var
2883 self.__callback = callback
2884 def __call__(self, *args):
2885 self.__var.set(self.__value)
2886 if self.__callback:
2887 apply(self.__callback, (self.__value,)+args)
Guido van Rossum28574b51996-10-21 15:16:51 +00002888
2889class OptionMenu(Menubutton):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002890 """OptionMenu which allows the user to select a value from a menu."""
2891 def __init__(self, master, variable, value, *values, **kwargs):
2892 """Construct an optionmenu widget with the parent MASTER, with
2893 the resource textvariable set to VARIABLE, the initially selected
2894 value VALUE, the other menu values VALUES and an additional
2895 keyword argument command."""
2896 kw = {"borderwidth": 2, "textvariable": variable,
2897 "indicatoron": 1, "relief": RAISED, "anchor": "c",
2898 "highlightthickness": 2}
2899 Widget.__init__(self, master, "menubutton", kw)
2900 self.widgetName = 'tk_optionMenu'
2901 menu = self.__menu = Menu(self, name="menu", tearoff=0)
2902 self.menuname = menu._w
2903 # 'command' is the only supported keyword
2904 callback = kwargs.get('command')
2905 if kwargs.has_key('command'):
2906 del kwargs['command']
2907 if kwargs:
2908 raise TclError, 'unknown option -'+kwargs.keys()[0]
2909 menu.add_command(label=value,
2910 command=_setit(variable, value, callback))
2911 for v in values:
2912 menu.add_command(label=v,
2913 command=_setit(variable, v, callback))
2914 self["menu"] = menu
Guido van Rossum28574b51996-10-21 15:16:51 +00002915
Fredrik Lundh06d28152000-08-09 18:03:12 +00002916 def __getitem__(self, name):
2917 if name == 'menu':
2918 return self.__menu
2919 return Widget.__getitem__(self, name)
Guido van Rossum28574b51996-10-21 15:16:51 +00002920
Fredrik Lundh06d28152000-08-09 18:03:12 +00002921 def destroy(self):
2922 """Destroy this widget and the associated menu."""
2923 Menubutton.destroy(self)
2924 self.__menu = None
Guido van Rossumbf4d8f91995-09-01 20:35:37 +00002925
Guido van Rossum35f67fb1995-08-04 03:50:29 +00002926class Image:
Fredrik Lundh06d28152000-08-09 18:03:12 +00002927 """Base class for images."""
Martin v. Löwis0d8ce612000-09-08 16:28:30 +00002928 _last_id = 0
Fredrik Lundh06d28152000-08-09 18:03:12 +00002929 def __init__(self, imgtype, name=None, cnf={}, master=None, **kw):
2930 self.name = None
2931 if not master:
2932 master = _default_root
2933 if not master:
2934 raise RuntimeError, 'Too early to create image'
2935 self.tk = master.tk
2936 if not name:
Martin v. Löwis0d8ce612000-09-08 16:28:30 +00002937 Image._last_id += 1
2938 name = "pyimage" +`Image._last_id` # tk itself would use image<x>
Fredrik Lundh06d28152000-08-09 18:03:12 +00002939 # The following is needed for systems where id(x)
2940 # can return a negative number, such as Linux/m68k:
2941 if name[0] == '-': name = '_' + name[1:]
2942 if kw and cnf: cnf = _cnfmerge((cnf, kw))
2943 elif kw: cnf = kw
2944 options = ()
2945 for k, v in cnf.items():
2946 if callable(v):
2947 v = self._register(v)
2948 options = options + ('-'+k, v)
2949 self.tk.call(('image', 'create', imgtype, name,) + options)
2950 self.name = name
2951 def __str__(self): return self.name
2952 def __del__(self):
2953 if self.name:
2954 try:
2955 self.tk.call('image', 'delete', self.name)
2956 except TclError:
2957 # May happen if the root was destroyed
2958 pass
2959 def __setitem__(self, key, value):
2960 self.tk.call(self.name, 'configure', '-'+key, value)
2961 def __getitem__(self, key):
2962 return self.tk.call(self.name, 'configure', '-'+key)
2963 def configure(self, **kw):
2964 """Configure the image."""
2965 res = ()
2966 for k, v in _cnfmerge(kw).items():
2967 if v is not None:
2968 if k[-1] == '_': k = k[:-1]
2969 if callable(v):
2970 v = self._register(v)
2971 res = res + ('-'+k, v)
2972 self.tk.call((self.name, 'config') + res)
2973 config = configure
2974 def height(self):
2975 """Return the height of the image."""
2976 return getint(
2977 self.tk.call('image', 'height', self.name))
2978 def type(self):
2979 """Return the type of the imgage, e.g. "photo" or "bitmap"."""
2980 return self.tk.call('image', 'type', self.name)
2981 def width(self):
2982 """Return the width of the image."""
2983 return getint(
2984 self.tk.call('image', 'width', self.name))
Guido van Rossum35f67fb1995-08-04 03:50:29 +00002985
2986class PhotoImage(Image):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002987 """Widget which can display colored images in GIF, PPM/PGM format."""
2988 def __init__(self, name=None, cnf={}, master=None, **kw):
2989 """Create an image with NAME.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002990
Fredrik Lundh06d28152000-08-09 18:03:12 +00002991 Valid resource names: data, format, file, gamma, height, palette,
2992 width."""
2993 apply(Image.__init__, (self, 'photo', name, cnf, master), kw)
2994 def blank(self):
2995 """Display a transparent image."""
2996 self.tk.call(self.name, 'blank')
2997 def cget(self, option):
2998 """Return the value of OPTION."""
2999 return self.tk.call(self.name, 'cget', '-' + option)
3000 # XXX config
3001 def __getitem__(self, key):
3002 return self.tk.call(self.name, 'cget', '-' + key)
3003 # XXX copy -from, -to, ...?
3004 def copy(self):
3005 """Return a new PhotoImage with the same image as this widget."""
3006 destImage = PhotoImage()
3007 self.tk.call(destImage, 'copy', self.name)
3008 return destImage
3009 def zoom(self,x,y=''):
3010 """Return a new PhotoImage with the same image as this widget
3011 but zoom it with X and Y."""
3012 destImage = PhotoImage()
3013 if y=='': y=x
3014 self.tk.call(destImage, 'copy', self.name, '-zoom',x,y)
3015 return destImage
3016 def subsample(self,x,y=''):
3017 """Return a new PhotoImage based on the same image as this widget
3018 but use only every Xth or Yth pixel."""
3019 destImage = PhotoImage()
3020 if y=='': y=x
3021 self.tk.call(destImage, 'copy', self.name, '-subsample',x,y)
3022 return destImage
3023 def get(self, x, y):
3024 """Return the color (red, green, blue) of the pixel at X,Y."""
3025 return self.tk.call(self.name, 'get', x, y)
3026 def put(self, data, to=None):
3027 """Put row formated colors to image starting from
3028 position TO, e.g. image.put("{red green} {blue yellow}", to=(4,6))"""
3029 args = (self.name, 'put', data)
3030 if to:
3031 if to[0] == '-to':
3032 to = to[1:]
3033 args = args + ('-to',) + tuple(to)
3034 self.tk.call(args)
3035 # XXX read
3036 def write(self, filename, format=None, from_coords=None):
3037 """Write image to file FILENAME in FORMAT starting from
3038 position FROM_COORDS."""
3039 args = (self.name, 'write', filename)
3040 if format:
3041 args = args + ('-format', format)
3042 if from_coords:
3043 args = args + ('-from',) + tuple(from_coords)
3044 self.tk.call(args)
Guido van Rossum35f67fb1995-08-04 03:50:29 +00003045
3046class BitmapImage(Image):
Fredrik Lundh06d28152000-08-09 18:03:12 +00003047 """Widget which can display a bitmap."""
3048 def __init__(self, name=None, cnf={}, master=None, **kw):
3049 """Create a bitmap with NAME.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00003050
Fredrik Lundh06d28152000-08-09 18:03:12 +00003051 Valid resource names: background, data, file, foreground, maskdata, maskfile."""
3052 apply(Image.__init__, (self, 'bitmap', name, cnf, master), kw)
Guido van Rossum35f67fb1995-08-04 03:50:29 +00003053
3054def image_names(): return _default_root.tk.call('image', 'names')
3055def image_types(): return _default_root.tk.call('image', 'types')
3056
Guido van Rossumaec5dc91994-06-27 07:55:12 +00003057######################################################################
3058# Extensions:
3059
3060class Studbutton(Button):
Fredrik Lundh06d28152000-08-09 18:03:12 +00003061 def __init__(self, master=None, cnf={}, **kw):
3062 Widget.__init__(self, master, 'studbutton', cnf, kw)
3063 self.bind('<Any-Enter>', self.tkButtonEnter)
3064 self.bind('<Any-Leave>', self.tkButtonLeave)
3065 self.bind('<1>', self.tkButtonDown)
3066 self.bind('<ButtonRelease-1>', self.tkButtonUp)
Guido van Rossumaec5dc91994-06-27 07:55:12 +00003067
3068class Tributton(Button):
Fredrik Lundh06d28152000-08-09 18:03:12 +00003069 def __init__(self, master=None, cnf={}, **kw):
3070 Widget.__init__(self, master, 'tributton', cnf, kw)
3071 self.bind('<Any-Enter>', self.tkButtonEnter)
3072 self.bind('<Any-Leave>', self.tkButtonLeave)
3073 self.bind('<1>', self.tkButtonDown)
3074 self.bind('<ButtonRelease-1>', self.tkButtonUp)
3075 self['fg'] = self['bg']
3076 self['activebackground'] = self['bg']
Guido van Rossum37dcab11996-05-16 16:00:19 +00003077
Guido van Rossumc417ef81996-08-21 23:38:59 +00003078######################################################################
3079# Test:
3080
3081def _test():
Fredrik Lundh06d28152000-08-09 18:03:12 +00003082 root = Tk()
3083 text = "This is Tcl/Tk version %s" % TclVersion
3084 if TclVersion >= 8.1:
Fredrik Lundh8fffa202000-08-09 18:51:01 +00003085 try:
3086 text = text + unicode("\nThis should be a cedilla: \347",
3087 "iso-8859-1")
3088 except NameError:
3089 pass # no unicode support
Fredrik Lundh06d28152000-08-09 18:03:12 +00003090 label = Label(root, text=text)
3091 label.pack()
3092 test = Button(root, text="Click me!",
3093 command=lambda root=root: root.test.configure(
3094 text="[%s]" % root.test['text']))
3095 test.pack()
3096 root.test = test
3097 quit = Button(root, text="QUIT", command=root.destroy)
3098 quit.pack()
3099 # The following three commands are needed so the window pops
3100 # up on top on Windows...
3101 root.iconify()
3102 root.update()
3103 root.deiconify()
3104 root.mainloop()
Guido van Rossumc417ef81996-08-21 23:38:59 +00003105
3106if __name__ == '__main__':
Fredrik Lundh06d28152000-08-09 18:03:12 +00003107 _test()