blob: da436c1999f9404d87b0fcebb931077c6a756bd9 [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,
6Checkbutton, Scale, Listbox, Scrollbar, OptionMenu. Properties of the widgets are
7specified with keyword arguments. Keyword arguments have the same
8name as the corresponding resource under Tk.
9
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
14Actions are bound to events by resources (e.g. keyword argument command) or
15with the method bind.
16
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 '',
851 funcid,
Eric S. Raymondfc170b12001-02-09 11:51:27 +0000852 " ".join(self._subst_format)))
Fredrik Lundh06d28152000-08-09 18:03:12 +0000853 self.tk.call(what + (sequence, cmd))
854 return funcid
855 elif sequence:
856 return self.tk.call(what + (sequence,))
857 else:
858 return self.tk.splitlist(self.tk.call(what))
859 def bind(self, sequence=None, func=None, add=None):
860 """Bind to this widget at event SEQUENCE a call to function FUNC.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000861
Fredrik Lundh06d28152000-08-09 18:03:12 +0000862 SEQUENCE is a string of concatenated event
863 patterns. An event pattern is of the form
864 <MODIFIER-MODIFIER-TYPE-DETAIL> where MODIFIER is one
865 of Control, Mod2, M2, Shift, Mod3, M3, Lock, Mod4, M4,
866 Button1, B1, Mod5, M5 Button2, B2, Meta, M, Button3,
867 B3, Alt, Button4, B4, Double, Button5, B5 Triple,
868 Mod1, M1. TYPE is one of Activate, Enter, Map,
869 ButtonPress, Button, Expose, Motion, ButtonRelease
870 FocusIn, MouseWheel, Circulate, FocusOut, Property,
871 Colormap, Gravity Reparent, Configure, KeyPress, Key,
872 Unmap, Deactivate, KeyRelease Visibility, Destroy,
873 Leave and DETAIL is the button number for ButtonPress,
874 ButtonRelease and DETAIL is the Keysym for KeyPress and
875 KeyRelease. Examples are
876 <Control-Button-1> for pressing Control and mouse button 1 or
877 <Alt-A> for pressing A and the Alt key (KeyPress can be omitted).
878 An event pattern can also be a virtual event of the form
879 <<AString>> where AString can be arbitrary. This
880 event can be generated by event_generate.
881 If events are concatenated they must appear shortly
882 after each other.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000883
Fredrik Lundh06d28152000-08-09 18:03:12 +0000884 FUNC will be called if the event sequence occurs with an
885 instance of Event as argument. If the return value of FUNC is
886 "break" no further bound function is invoked.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000887
Fredrik Lundh06d28152000-08-09 18:03:12 +0000888 An additional boolean parameter ADD specifies whether FUNC will
889 be called additionally to the other bound function or whether
890 it will replace the previous function.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000891
Fredrik Lundh06d28152000-08-09 18:03:12 +0000892 Bind will return an identifier to allow deletion of the bound function with
893 unbind without memory leak.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000894
Fredrik Lundh06d28152000-08-09 18:03:12 +0000895 If FUNC or SEQUENCE is omitted the bound function or list
896 of bound events are returned."""
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000897
Fredrik Lundh06d28152000-08-09 18:03:12 +0000898 return self._bind(('bind', self._w), sequence, func, add)
899 def unbind(self, sequence, funcid=None):
900 """Unbind for this widget for event SEQUENCE the
901 function identified with FUNCID."""
902 self.tk.call('bind', self._w, sequence, '')
903 if funcid:
904 self.deletecommand(funcid)
905 def bind_all(self, sequence=None, func=None, add=None):
906 """Bind to all widgets at an event SEQUENCE a call to function FUNC.
907 An additional boolean parameter ADD specifies whether FUNC will
908 be called additionally to the other bound function or whether
909 it will replace the previous function. See bind for the return value."""
910 return self._bind(('bind', 'all'), sequence, func, add, 0)
911 def unbind_all(self, sequence):
912 """Unbind for all widgets for event SEQUENCE all functions."""
913 self.tk.call('bind', 'all' , sequence, '')
914 def bind_class(self, className, sequence=None, func=None, add=None):
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000915
Fredrik Lundh06d28152000-08-09 18:03:12 +0000916 """Bind to widgets with bindtag CLASSNAME at event
917 SEQUENCE a call of function FUNC. An additional
918 boolean parameter ADD specifies whether FUNC will be
919 called additionally to the other bound function or
920 whether it will replace the previous function. See bind for
921 the return value."""
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000922
Fredrik Lundh06d28152000-08-09 18:03:12 +0000923 return self._bind(('bind', className), sequence, func, add, 0)
924 def unbind_class(self, className, sequence):
925 """Unbind for a all widgets with bindtag CLASSNAME for event SEQUENCE
926 all functions."""
927 self.tk.call('bind', className , sequence, '')
928 def mainloop(self, n=0):
929 """Call the mainloop of Tk."""
930 self.tk.mainloop(n)
931 def quit(self):
932 """Quit the Tcl interpreter. All widgets will be destroyed."""
933 self.tk.quit()
934 def _getints(self, string):
935 """Internal function."""
936 if string:
937 return tuple(map(getint, self.tk.splitlist(string)))
938 def _getdoubles(self, string):
939 """Internal function."""
940 if string:
941 return tuple(map(getdouble, self.tk.splitlist(string)))
942 def _getboolean(self, string):
943 """Internal function."""
944 if string:
945 return self.tk.getboolean(string)
946 def _displayof(self, displayof):
947 """Internal function."""
948 if displayof:
949 return ('-displayof', displayof)
950 if displayof is None:
951 return ('-displayof', self._w)
952 return ()
953 def _options(self, cnf, kw = None):
954 """Internal function."""
955 if kw:
956 cnf = _cnfmerge((cnf, kw))
957 else:
958 cnf = _cnfmerge(cnf)
959 res = ()
960 for k, v in cnf.items():
961 if v is not None:
962 if k[-1] == '_': k = k[:-1]
963 if callable(v):
964 v = self._register(v)
965 res = res + ('-'+k, v)
966 return res
967 def nametowidget(self, name):
968 """Return the Tkinter instance of a widget identified by
969 its Tcl name NAME."""
970 w = self
971 if name[0] == '.':
972 w = w._root()
973 name = name[1:]
Fredrik Lundh06d28152000-08-09 18:03:12 +0000974 while name:
Eric S. Raymondfc170b12001-02-09 11:51:27 +0000975 i = name.find('.')
Fredrik Lundh06d28152000-08-09 18:03:12 +0000976 if i >= 0:
977 name, tail = name[:i], name[i+1:]
978 else:
979 tail = ''
980 w = w.children[name]
981 name = tail
982 return w
983 _nametowidget = nametowidget
984 def _register(self, func, subst=None, needcleanup=1):
985 """Return a newly created Tcl function. If this
986 function is called, the Python function FUNC will
987 be executed. An optional function SUBST can
988 be given which will be executed before FUNC."""
989 f = CallWrapper(func, subst, self).__call__
990 name = `id(f)`
991 try:
992 func = func.im_func
993 except AttributeError:
994 pass
995 try:
996 name = name + func.__name__
997 except AttributeError:
998 pass
999 self.tk.createcommand(name, f)
1000 if needcleanup:
1001 if self._tclCommands is None:
1002 self._tclCommands = []
1003 self._tclCommands.append(name)
1004 #print '+ Tkinter created command', name
1005 return name
1006 register = _register
1007 def _root(self):
1008 """Internal function."""
1009 w = self
1010 while w.master: w = w.master
1011 return w
1012 _subst_format = ('%#', '%b', '%f', '%h', '%k',
1013 '%s', '%t', '%w', '%x', '%y',
1014 '%A', '%E', '%K', '%N', '%W', '%T', '%X', '%Y', '%D')
1015 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)
1481 if _MacOS:
1482 # 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 Rossum18468821994-06-20 07:49:28 +00002366
2367class Menu(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002368 """Menu widget which allows to display menu bars, pull-down menus and pop-up menus."""
2369 def __init__(self, master=None, cnf={}, **kw):
2370 """Construct menu widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002371
Fredrik Lundh06d28152000-08-09 18:03:12 +00002372 Valid resource names: activebackground, activeborderwidth,
2373 activeforeground, background, bd, bg, borderwidth, cursor,
2374 disabledforeground, fg, font, foreground, postcommand, relief,
2375 selectcolor, takefocus, tearoff, tearoffcommand, title, type."""
2376 Widget.__init__(self, master, 'menu', cnf, kw)
2377 def tk_bindForTraversal(self):
2378 pass # obsolete since Tk 4.0
2379 def tk_mbPost(self):
2380 self.tk.call('tk_mbPost', self._w)
2381 def tk_mbUnpost(self):
2382 self.tk.call('tk_mbUnpost')
2383 def tk_traverseToMenu(self, char):
2384 self.tk.call('tk_traverseToMenu', self._w, char)
2385 def tk_traverseWithinMenu(self, char):
2386 self.tk.call('tk_traverseWithinMenu', self._w, char)
2387 def tk_getMenuButtons(self):
2388 return self.tk.call('tk_getMenuButtons', self._w)
2389 def tk_nextMenu(self, count):
2390 self.tk.call('tk_nextMenu', count)
2391 def tk_nextMenuEntry(self, count):
2392 self.tk.call('tk_nextMenuEntry', count)
2393 def tk_invokeMenu(self):
2394 self.tk.call('tk_invokeMenu', self._w)
2395 def tk_firstMenu(self):
2396 self.tk.call('tk_firstMenu', self._w)
2397 def tk_mbButtonDown(self):
2398 self.tk.call('tk_mbButtonDown', self._w)
2399 def tk_popup(self, x, y, entry=""):
2400 """Post the menu at position X,Y with entry ENTRY."""
2401 self.tk.call('tk_popup', self._w, x, y, entry)
2402 def activate(self, index):
2403 """Activate entry at INDEX."""
2404 self.tk.call(self._w, 'activate', index)
2405 def add(self, itemType, cnf={}, **kw):
2406 """Internal function."""
2407 self.tk.call((self._w, 'add', itemType) +
2408 self._options(cnf, kw))
2409 def add_cascade(self, cnf={}, **kw):
2410 """Add hierarchical menu item."""
2411 self.add('cascade', cnf or kw)
2412 def add_checkbutton(self, cnf={}, **kw):
2413 """Add checkbutton menu item."""
2414 self.add('checkbutton', cnf or kw)
2415 def add_command(self, cnf={}, **kw):
2416 """Add command menu item."""
2417 self.add('command', cnf or kw)
2418 def add_radiobutton(self, cnf={}, **kw):
2419 """Addd radio menu item."""
2420 self.add('radiobutton', cnf or kw)
2421 def add_separator(self, cnf={}, **kw):
2422 """Add separator."""
2423 self.add('separator', cnf or kw)
2424 def insert(self, index, itemType, cnf={}, **kw):
2425 """Internal function."""
2426 self.tk.call((self._w, 'insert', index, itemType) +
2427 self._options(cnf, kw))
2428 def insert_cascade(self, index, cnf={}, **kw):
2429 """Add hierarchical menu item at INDEX."""
2430 self.insert(index, 'cascade', cnf or kw)
2431 def insert_checkbutton(self, index, cnf={}, **kw):
2432 """Add checkbutton menu item at INDEX."""
2433 self.insert(index, 'checkbutton', cnf or kw)
2434 def insert_command(self, index, cnf={}, **kw):
2435 """Add command menu item at INDEX."""
2436 self.insert(index, 'command', cnf or kw)
2437 def insert_radiobutton(self, index, cnf={}, **kw):
2438 """Addd radio menu item at INDEX."""
2439 self.insert(index, 'radiobutton', cnf or kw)
2440 def insert_separator(self, index, cnf={}, **kw):
2441 """Add separator at INDEX."""
2442 self.insert(index, 'separator', cnf or kw)
2443 def delete(self, index1, index2=None):
2444 """Delete menu items between INDEX1 and INDEX2 (not included)."""
2445 self.tk.call(self._w, 'delete', index1, index2)
2446 def entrycget(self, index, option):
2447 """Return the resource value of an menu item for OPTION at INDEX."""
2448 return self.tk.call(self._w, 'entrycget', index, '-' + option)
2449 def entryconfigure(self, index, cnf=None, **kw):
2450 """Configure a menu item at INDEX."""
2451 if cnf is None and not kw:
2452 cnf = {}
2453 for x in self.tk.split(self.tk.call(
2454 (self._w, 'entryconfigure', index))):
2455 cnf[x[0][1:]] = (x[0][1:],) + x[1:]
2456 return cnf
2457 if type(cnf) == StringType and not kw:
2458 x = self.tk.split(self.tk.call(
2459 (self._w, 'entryconfigure', index, '-'+cnf)))
2460 return (x[0][1:],) + x[1:]
2461 self.tk.call((self._w, 'entryconfigure', index)
2462 + self._options(cnf, kw))
2463 entryconfig = entryconfigure
2464 def index(self, index):
2465 """Return the index of a menu item identified by INDEX."""
2466 i = self.tk.call(self._w, 'index', index)
2467 if i == 'none': return None
2468 return getint(i)
2469 def invoke(self, index):
2470 """Invoke a menu item identified by INDEX and execute
2471 the associated command."""
2472 return self.tk.call(self._w, 'invoke', index)
2473 def post(self, x, y):
2474 """Display a menu at position X,Y."""
2475 self.tk.call(self._w, 'post', x, y)
2476 def type(self, index):
2477 """Return the type of the menu item at INDEX."""
2478 return self.tk.call(self._w, 'type', index)
2479 def unpost(self):
2480 """Unmap a menu."""
2481 self.tk.call(self._w, 'unpost')
2482 def yposition(self, index):
2483 """Return the y-position of the topmost pixel of the menu item at INDEX."""
2484 return getint(self.tk.call(
2485 self._w, 'yposition', index))
Guido van Rossum18468821994-06-20 07:49:28 +00002486
2487class Menubutton(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002488 """Menubutton widget, obsolete since Tk8.0."""
2489 def __init__(self, master=None, cnf={}, **kw):
2490 Widget.__init__(self, master, 'menubutton', cnf, kw)
Guido van Rossum18468821994-06-20 07:49:28 +00002491
2492class Message(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002493 """Message widget to display multiline text. Obsolete since Label does it too."""
2494 def __init__(self, master=None, cnf={}, **kw):
2495 Widget.__init__(self, master, 'message', cnf, kw)
Guido van Rossum18468821994-06-20 07:49:28 +00002496
2497class Radiobutton(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002498 """Radiobutton widget which shows only one of several buttons in on-state."""
2499 def __init__(self, master=None, cnf={}, **kw):
2500 """Construct a radiobutton widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002501
Fredrik Lundh06d28152000-08-09 18:03:12 +00002502 Valid resource names: activebackground, activeforeground, anchor,
2503 background, bd, bg, bitmap, borderwidth, command, cursor,
2504 disabledforeground, fg, font, foreground, height,
2505 highlightbackground, highlightcolor, highlightthickness, image,
2506 indicatoron, justify, padx, pady, relief, selectcolor, selectimage,
2507 state, takefocus, text, textvariable, underline, value, variable,
2508 width, wraplength."""
2509 Widget.__init__(self, master, 'radiobutton', cnf, kw)
2510 def deselect(self):
2511 """Put the button in off-state."""
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002512
Fredrik Lundh06d28152000-08-09 18:03:12 +00002513 self.tk.call(self._w, 'deselect')
2514 def flash(self):
2515 """Flash the button."""
2516 self.tk.call(self._w, 'flash')
2517 def invoke(self):
2518 """Toggle the button and invoke a command if given as resource."""
2519 return self.tk.call(self._w, 'invoke')
2520 def select(self):
2521 """Put the button in on-state."""
2522 self.tk.call(self._w, 'select')
Guido van Rossum18468821994-06-20 07:49:28 +00002523
2524class Scale(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002525 """Scale widget which can display a numerical scale."""
2526 def __init__(self, master=None, cnf={}, **kw):
2527 """Construct a scale widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002528
Fredrik Lundh06d28152000-08-09 18:03:12 +00002529 Valid resource names: activebackground, background, bigincrement, bd,
2530 bg, borderwidth, command, cursor, digits, fg, font, foreground, from,
2531 highlightbackground, highlightcolor, highlightthickness, label,
2532 length, orient, relief, repeatdelay, repeatinterval, resolution,
2533 showvalue, sliderlength, sliderrelief, state, takefocus,
2534 tickinterval, to, troughcolor, variable, width."""
2535 Widget.__init__(self, master, 'scale', cnf, kw)
2536 def get(self):
2537 """Get the current value as integer or float."""
2538 value = self.tk.call(self._w, 'get')
2539 try:
2540 return getint(value)
2541 except ValueError:
2542 return getdouble(value)
2543 def set(self, value):
2544 """Set the value to VALUE."""
2545 self.tk.call(self._w, 'set', value)
2546 def coords(self, value=None):
2547 """Return a tuple (X,Y) of the point along the centerline of the
2548 trough that corresponds to VALUE or the current value if None is
2549 given."""
2550
2551 return self._getints(self.tk.call(self._w, 'coords', value))
2552 def identify(self, x, y):
2553 """Return where the point X,Y lies. Valid return values are "slider",
2554 "though1" and "though2"."""
2555 return self.tk.call(self._w, 'identify', x, y)
Guido van Rossum18468821994-06-20 07:49:28 +00002556
2557class Scrollbar(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002558 """Scrollbar widget which displays a slider at a certain position."""
2559 def __init__(self, master=None, cnf={}, **kw):
2560 """Construct a scrollbar widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002561
Fredrik Lundh06d28152000-08-09 18:03:12 +00002562 Valid resource names: activebackground, activerelief,
2563 background, bd, bg, borderwidth, command, cursor,
2564 elementborderwidth, highlightbackground,
2565 highlightcolor, highlightthickness, jump, orient,
2566 relief, repeatdelay, repeatinterval, takefocus,
2567 troughcolor, width."""
2568 Widget.__init__(self, master, 'scrollbar', cnf, kw)
2569 def activate(self, index):
2570 """Display the element at INDEX with activebackground and activerelief.
2571 INDEX can be "arrow1","slider" or "arrow2"."""
2572 self.tk.call(self._w, 'activate', index)
2573 def delta(self, deltax, deltay):
2574 """Return the fractional change of the scrollbar setting if it
2575 would be moved by DELTAX or DELTAY pixels."""
2576 return getdouble(
2577 self.tk.call(self._w, 'delta', deltax, deltay))
2578 def fraction(self, x, y):
2579 """Return the fractional value which corresponds to a slider
2580 position of X,Y."""
2581 return getdouble(self.tk.call(self._w, 'fraction', x, y))
2582 def identify(self, x, y):
2583 """Return the element under position X,Y as one of
2584 "arrow1","slider","arrow2" or ""."""
2585 return self.tk.call(self._w, 'identify', x, y)
2586 def get(self):
2587 """Return the current fractional values (upper and lower end)
2588 of the slider position."""
2589 return self._getdoubles(self.tk.call(self._w, 'get'))
2590 def set(self, *args):
2591 """Set the fractional values of the slider position (upper and
2592 lower ends as value between 0 and 1)."""
2593 self.tk.call((self._w, 'set') + args)
Guido van Rossum18468821994-06-20 07:49:28 +00002594
2595class Text(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002596 """Text widget which can display text in various forms."""
2597 # XXX Add dump()
2598 def __init__(self, master=None, cnf={}, **kw):
2599 """Construct a text widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002600
Fredrik Lundh06d28152000-08-09 18:03:12 +00002601 Valid resource names: background, bd, bg, borderwidth, cursor,
2602 exportselection, fg, font, foreground, height,
2603 highlightbackground, highlightcolor, highlightthickness,
2604 insertbackground, insertborderwidth, insertofftime,
2605 insertontime, insertwidth, padx, pady, relief,
2606 selectbackground, selectborderwidth, selectforeground,
2607 setgrid, spacing1, spacing2, spacing3, state, tabs, takefocus,
2608 width, wrap, xscrollcommand, yscrollcommand."""
2609 Widget.__init__(self, master, 'text', cnf, kw)
2610 def bbox(self, *args):
2611 """Return a tuple of (x,y,width,height) which gives the bounding
2612 box of the visible part of the character at the index in ARGS."""
2613 return self._getints(
2614 self.tk.call((self._w, 'bbox') + args)) or None
2615 def tk_textSelectTo(self, index):
2616 self.tk.call('tk_textSelectTo', self._w, index)
2617 def tk_textBackspace(self):
2618 self.tk.call('tk_textBackspace', self._w)
2619 def tk_textIndexCloser(self, a, b, c):
2620 self.tk.call('tk_textIndexCloser', self._w, a, b, c)
2621 def tk_textResetAnchor(self, index):
2622 self.tk.call('tk_textResetAnchor', self._w, index)
2623 def compare(self, index1, op, index2):
2624 """Return whether between index INDEX1 and index INDEX2 the
2625 relation OP is satisfied. OP is one of <, <=, ==, >=, >, or !=."""
2626 return self.tk.getboolean(self.tk.call(
2627 self._w, 'compare', index1, op, index2))
2628 def debug(self, boolean=None):
2629 """Turn on the internal consistency checks of the B-Tree inside the text
2630 widget according to BOOLEAN."""
2631 return self.tk.getboolean(self.tk.call(
2632 self._w, 'debug', boolean))
2633 def delete(self, index1, index2=None):
2634 """Delete the characters between INDEX1 and INDEX2 (not included)."""
2635 self.tk.call(self._w, 'delete', index1, index2)
2636 def dlineinfo(self, index):
2637 """Return tuple (x,y,width,height,baseline) giving the bounding box
2638 and baseline position of the visible part of the line containing
2639 the character at INDEX."""
2640 return self._getints(self.tk.call(self._w, 'dlineinfo', index))
2641 def get(self, index1, index2=None):
2642 """Return the text from INDEX1 to INDEX2 (not included)."""
2643 return self.tk.call(self._w, 'get', index1, index2)
2644 # (Image commands are new in 8.0)
2645 def image_cget(self, index, option):
2646 """Return the value of OPTION of an embedded image at INDEX."""
2647 if option[:1] != "-":
2648 option = "-" + option
2649 if option[-1:] == "_":
2650 option = option[:-1]
2651 return self.tk.call(self._w, "image", "cget", index, option)
2652 def image_configure(self, index, cnf={}, **kw):
2653 """Configure an embedded image at INDEX."""
2654 if not cnf and not kw:
2655 cnf = {}
2656 for x in self.tk.split(
2657 self.tk.call(
2658 self._w, "image", "configure", index)):
2659 cnf[x[0][1:]] = (x[0][1:],) + x[1:]
2660 return cnf
2661 apply(self.tk.call,
2662 (self._w, "image", "configure", index)
2663 + self._options(cnf, kw))
2664 def image_create(self, index, cnf={}, **kw):
2665 """Create an embedded image at INDEX."""
2666 return apply(self.tk.call,
2667 (self._w, "image", "create", index)
2668 + self._options(cnf, kw))
2669 def image_names(self):
2670 """Return all names of embedded images in this widget."""
2671 return self.tk.call(self._w, "image", "names")
2672 def index(self, index):
2673 """Return the index in the form line.char for INDEX."""
2674 return self.tk.call(self._w, 'index', index)
2675 def insert(self, index, chars, *args):
2676 """Insert CHARS before the characters at INDEX. An additional
2677 tag can be given in ARGS. Additional CHARS and tags can follow in ARGS."""
2678 self.tk.call((self._w, 'insert', index, chars) + args)
2679 def mark_gravity(self, markName, direction=None):
2680 """Change the gravity of a mark MARKNAME to DIRECTION (LEFT or RIGHT).
2681 Return the current value if None is given for DIRECTION."""
2682 return self.tk.call(
2683 (self._w, 'mark', 'gravity', markName, direction))
2684 def mark_names(self):
2685 """Return all mark names."""
2686 return self.tk.splitlist(self.tk.call(
2687 self._w, 'mark', 'names'))
2688 def mark_set(self, markName, index):
2689 """Set mark MARKNAME before the character at INDEX."""
2690 self.tk.call(self._w, 'mark', 'set', markName, index)
2691 def mark_unset(self, *markNames):
2692 """Delete all marks in MARKNAMES."""
2693 self.tk.call((self._w, 'mark', 'unset') + markNames)
2694 def mark_next(self, index):
2695 """Return the name of the next mark after INDEX."""
2696 return self.tk.call(self._w, 'mark', 'next', index) or None
2697 def mark_previous(self, index):
2698 """Return the name of the previous mark before INDEX."""
2699 return self.tk.call(self._w, 'mark', 'previous', index) or None
2700 def scan_mark(self, x, y):
2701 """Remember the current X, Y coordinates."""
2702 self.tk.call(self._w, 'scan', 'mark', x, y)
2703 def scan_dragto(self, x, y):
2704 """Adjust the view of the text to 10 times the
2705 difference between X and Y and the coordinates given in
2706 scan_mark."""
2707 self.tk.call(self._w, 'scan', 'dragto', x, y)
2708 def search(self, pattern, index, stopindex=None,
2709 forwards=None, backwards=None, exact=None,
2710 regexp=None, nocase=None, count=None):
2711 """Search PATTERN beginning from INDEX until STOPINDEX.
2712 Return the index of the first character of a match or an empty string."""
2713 args = [self._w, 'search']
2714 if forwards: args.append('-forwards')
2715 if backwards: args.append('-backwards')
2716 if exact: args.append('-exact')
2717 if regexp: args.append('-regexp')
2718 if nocase: args.append('-nocase')
2719 if count: args.append('-count'); args.append(count)
2720 if pattern[0] == '-': args.append('--')
2721 args.append(pattern)
2722 args.append(index)
2723 if stopindex: args.append(stopindex)
2724 return self.tk.call(tuple(args))
2725 def see(self, index):
2726 """Scroll such that the character at INDEX is visible."""
2727 self.tk.call(self._w, 'see', index)
2728 def tag_add(self, tagName, index1, *args):
2729 """Add tag TAGNAME to all characters between INDEX1 and index2 in ARGS.
2730 Additional pairs of indices may follow in ARGS."""
2731 self.tk.call(
2732 (self._w, 'tag', 'add', tagName, index1) + args)
2733 def tag_unbind(self, tagName, sequence, funcid=None):
2734 """Unbind for all characters with TAGNAME for event SEQUENCE the
2735 function identified with FUNCID."""
2736 self.tk.call(self._w, 'tag', 'bind', tagName, sequence, '')
2737 if funcid:
2738 self.deletecommand(funcid)
2739 def tag_bind(self, tagName, sequence, func, add=None):
2740 """Bind to all characters with TAGNAME at event SEQUENCE a call to function FUNC.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002741
Fredrik Lundh06d28152000-08-09 18:03:12 +00002742 An additional boolean parameter ADD specifies whether FUNC will be
2743 called additionally to the other bound function or whether it will
2744 replace the previous function. See bind for the return value."""
2745 return self._bind((self._w, 'tag', 'bind', tagName),
2746 sequence, func, add)
2747 def tag_cget(self, tagName, option):
2748 """Return the value of OPTION for tag TAGNAME."""
2749 if option[:1] != '-':
2750 option = '-' + option
2751 if option[-1:] == '_':
2752 option = option[:-1]
2753 return self.tk.call(self._w, 'tag', 'cget', tagName, option)
2754 def tag_configure(self, tagName, cnf={}, **kw):
2755 """Configure a tag TAGNAME."""
2756 if type(cnf) == StringType:
2757 x = self.tk.split(self.tk.call(
2758 self._w, 'tag', 'configure', tagName, '-'+cnf))
2759 return (x[0][1:],) + x[1:]
2760 self.tk.call(
2761 (self._w, 'tag', 'configure', tagName)
2762 + self._options(cnf, kw))
2763 tag_config = tag_configure
2764 def tag_delete(self, *tagNames):
2765 """Delete all tags in TAGNAMES."""
2766 self.tk.call((self._w, 'tag', 'delete') + tagNames)
2767 def tag_lower(self, tagName, belowThis=None):
2768 """Change the priority of tag TAGNAME such that it is lower
2769 than the priority of BELOWTHIS."""
2770 self.tk.call(self._w, 'tag', 'lower', tagName, belowThis)
2771 def tag_names(self, index=None):
2772 """Return a list of all tag names."""
2773 return self.tk.splitlist(
2774 self.tk.call(self._w, 'tag', 'names', index))
2775 def tag_nextrange(self, tagName, index1, index2=None):
2776 """Return a list of start and end index for the first sequence of
2777 characters between INDEX1 and INDEX2 which all have tag TAGNAME.
2778 The text is searched forward from INDEX1."""
2779 return self.tk.splitlist(self.tk.call(
2780 self._w, 'tag', 'nextrange', tagName, index1, index2))
2781 def tag_prevrange(self, tagName, index1, index2=None):
2782 """Return a list of start and end index for the first sequence of
2783 characters between INDEX1 and INDEX2 which all have tag TAGNAME.
2784 The text is searched backwards from INDEX1."""
2785 return self.tk.splitlist(self.tk.call(
2786 self._w, 'tag', 'prevrange', tagName, index1, index2))
2787 def tag_raise(self, tagName, aboveThis=None):
2788 """Change the priority of tag TAGNAME such that it is higher
2789 than the priority of ABOVETHIS."""
2790 self.tk.call(
2791 self._w, 'tag', 'raise', tagName, aboveThis)
2792 def tag_ranges(self, tagName):
2793 """Return a list of ranges of text which have tag TAGNAME."""
2794 return self.tk.splitlist(self.tk.call(
2795 self._w, 'tag', 'ranges', tagName))
2796 def tag_remove(self, tagName, index1, index2=None):
2797 """Remove tag TAGNAME from all characters between INDEX1 and INDEX2."""
2798 self.tk.call(
2799 self._w, 'tag', 'remove', tagName, index1, index2)
2800 def window_cget(self, index, option):
2801 """Return the value of OPTION of an embedded window at INDEX."""
2802 if option[:1] != '-':
2803 option = '-' + option
2804 if option[-1:] == '_':
2805 option = option[:-1]
2806 return self.tk.call(self._w, 'window', 'cget', index, option)
2807 def window_configure(self, index, cnf={}, **kw):
2808 """Configure an embedded window at INDEX."""
2809 if type(cnf) == StringType:
2810 x = self.tk.split(self.tk.call(
2811 self._w, 'window', 'configure',
2812 index, '-'+cnf))
2813 return (x[0][1:],) + x[1:]
2814 self.tk.call(
2815 (self._w, 'window', 'configure', index)
2816 + self._options(cnf, kw))
2817 window_config = window_configure
2818 def window_create(self, index, cnf={}, **kw):
2819 """Create a window at INDEX."""
2820 self.tk.call(
2821 (self._w, 'window', 'create', index)
2822 + self._options(cnf, kw))
2823 def window_names(self):
2824 """Return all names of embedded windows in this widget."""
2825 return self.tk.splitlist(
2826 self.tk.call(self._w, 'window', 'names'))
2827 def xview(self, *what):
2828 """Query and change horizontal position of the view."""
2829 if not what:
2830 return self._getdoubles(self.tk.call(self._w, 'xview'))
2831 self.tk.call((self._w, 'xview') + what)
Fredrik Lundh5bd2cd62000-08-09 18:29:51 +00002832 def xview_moveto(self, fraction):
2833 """Adjusts the view in the window so that FRACTION of the
2834 total width of the canvas is off-screen to the left."""
2835 self.tk.call(self._w, 'xview', 'moveto', fraction)
2836 def xview_scroll(self, number, what):
2837 """Shift the x-view according to NUMBER which is measured
2838 in "units" or "pages" (WHAT)."""
2839 self.tk.call(self._w, 'xview', 'scroll', number, what)
Fredrik Lundh8fffa202000-08-09 18:51:01 +00002840 def yview(self, *what):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002841 """Query and change vertical position of the view."""
Fredrik Lundh8fffa202000-08-09 18:51:01 +00002842 if not what:
Fredrik Lundh06d28152000-08-09 18:03:12 +00002843 return self._getdoubles(self.tk.call(self._w, 'yview'))
Fredrik Lundh8fffa202000-08-09 18:51:01 +00002844 self.tk.call((self._w, 'yview') + what)
Fredrik Lundh5bd2cd62000-08-09 18:29:51 +00002845 def yview_moveto(self, fraction):
2846 """Adjusts the view in the window so that FRACTION of the
2847 total height of the canvas is off-screen to the top."""
2848 self.tk.call(self._w, 'yview', 'moveto', fraction)
2849 def yview_scroll(self, number, what):
2850 """Shift the y-view according to NUMBER which is measured
2851 in "units" or "pages" (WHAT)."""
2852 self.tk.call(self._w, 'yview', 'scroll', number, what)
Fredrik Lundh06d28152000-08-09 18:03:12 +00002853 def yview_pickplace(self, *what):
2854 """Obsolete function, use see."""
2855 self.tk.call((self._w, 'yview', '-pickplace') + what)
Guido van Rossum18468821994-06-20 07:49:28 +00002856
Guido van Rossum28574b51996-10-21 15:16:51 +00002857class _setit:
Fredrik Lundh06d28152000-08-09 18:03:12 +00002858 """Internal class. It wraps the command in the widget OptionMenu."""
2859 def __init__(self, var, value, callback=None):
2860 self.__value = value
2861 self.__var = var
2862 self.__callback = callback
2863 def __call__(self, *args):
2864 self.__var.set(self.__value)
2865 if self.__callback:
2866 apply(self.__callback, (self.__value,)+args)
Guido van Rossum28574b51996-10-21 15:16:51 +00002867
2868class OptionMenu(Menubutton):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002869 """OptionMenu which allows the user to select a value from a menu."""
2870 def __init__(self, master, variable, value, *values, **kwargs):
2871 """Construct an optionmenu widget with the parent MASTER, with
2872 the resource textvariable set to VARIABLE, the initially selected
2873 value VALUE, the other menu values VALUES and an additional
2874 keyword argument command."""
2875 kw = {"borderwidth": 2, "textvariable": variable,
2876 "indicatoron": 1, "relief": RAISED, "anchor": "c",
2877 "highlightthickness": 2}
2878 Widget.__init__(self, master, "menubutton", kw)
2879 self.widgetName = 'tk_optionMenu'
2880 menu = self.__menu = Menu(self, name="menu", tearoff=0)
2881 self.menuname = menu._w
2882 # 'command' is the only supported keyword
2883 callback = kwargs.get('command')
2884 if kwargs.has_key('command'):
2885 del kwargs['command']
2886 if kwargs:
2887 raise TclError, 'unknown option -'+kwargs.keys()[0]
2888 menu.add_command(label=value,
2889 command=_setit(variable, value, callback))
2890 for v in values:
2891 menu.add_command(label=v,
2892 command=_setit(variable, v, callback))
2893 self["menu"] = menu
Guido van Rossum28574b51996-10-21 15:16:51 +00002894
Fredrik Lundh06d28152000-08-09 18:03:12 +00002895 def __getitem__(self, name):
2896 if name == 'menu':
2897 return self.__menu
2898 return Widget.__getitem__(self, name)
Guido van Rossum28574b51996-10-21 15:16:51 +00002899
Fredrik Lundh06d28152000-08-09 18:03:12 +00002900 def destroy(self):
2901 """Destroy this widget and the associated menu."""
2902 Menubutton.destroy(self)
2903 self.__menu = None
Guido van Rossumbf4d8f91995-09-01 20:35:37 +00002904
Guido van Rossum35f67fb1995-08-04 03:50:29 +00002905class Image:
Fredrik Lundh06d28152000-08-09 18:03:12 +00002906 """Base class for images."""
Martin v. Löwis0d8ce612000-09-08 16:28:30 +00002907 _last_id = 0
Fredrik Lundh06d28152000-08-09 18:03:12 +00002908 def __init__(self, imgtype, name=None, cnf={}, master=None, **kw):
2909 self.name = None
2910 if not master:
2911 master = _default_root
2912 if not master:
2913 raise RuntimeError, 'Too early to create image'
2914 self.tk = master.tk
2915 if not name:
Martin v. Löwis0d8ce612000-09-08 16:28:30 +00002916 Image._last_id += 1
2917 name = "pyimage" +`Image._last_id` # tk itself would use image<x>
Fredrik Lundh06d28152000-08-09 18:03:12 +00002918 # The following is needed for systems where id(x)
2919 # can return a negative number, such as Linux/m68k:
2920 if name[0] == '-': name = '_' + name[1:]
2921 if kw and cnf: cnf = _cnfmerge((cnf, kw))
2922 elif kw: cnf = kw
2923 options = ()
2924 for k, v in cnf.items():
2925 if callable(v):
2926 v = self._register(v)
2927 options = options + ('-'+k, v)
2928 self.tk.call(('image', 'create', imgtype, name,) + options)
2929 self.name = name
2930 def __str__(self): return self.name
2931 def __del__(self):
2932 if self.name:
2933 try:
2934 self.tk.call('image', 'delete', self.name)
2935 except TclError:
2936 # May happen if the root was destroyed
2937 pass
2938 def __setitem__(self, key, value):
2939 self.tk.call(self.name, 'configure', '-'+key, value)
2940 def __getitem__(self, key):
2941 return self.tk.call(self.name, 'configure', '-'+key)
2942 def configure(self, **kw):
2943 """Configure the image."""
2944 res = ()
2945 for k, v in _cnfmerge(kw).items():
2946 if v is not None:
2947 if k[-1] == '_': k = k[:-1]
2948 if callable(v):
2949 v = self._register(v)
2950 res = res + ('-'+k, v)
2951 self.tk.call((self.name, 'config') + res)
2952 config = configure
2953 def height(self):
2954 """Return the height of the image."""
2955 return getint(
2956 self.tk.call('image', 'height', self.name))
2957 def type(self):
2958 """Return the type of the imgage, e.g. "photo" or "bitmap"."""
2959 return self.tk.call('image', 'type', self.name)
2960 def width(self):
2961 """Return the width of the image."""
2962 return getint(
2963 self.tk.call('image', 'width', self.name))
Guido van Rossum35f67fb1995-08-04 03:50:29 +00002964
2965class PhotoImage(Image):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002966 """Widget which can display colored images in GIF, PPM/PGM format."""
2967 def __init__(self, name=None, cnf={}, master=None, **kw):
2968 """Create an image with NAME.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002969
Fredrik Lundh06d28152000-08-09 18:03:12 +00002970 Valid resource names: data, format, file, gamma, height, palette,
2971 width."""
2972 apply(Image.__init__, (self, 'photo', name, cnf, master), kw)
2973 def blank(self):
2974 """Display a transparent image."""
2975 self.tk.call(self.name, 'blank')
2976 def cget(self, option):
2977 """Return the value of OPTION."""
2978 return self.tk.call(self.name, 'cget', '-' + option)
2979 # XXX config
2980 def __getitem__(self, key):
2981 return self.tk.call(self.name, 'cget', '-' + key)
2982 # XXX copy -from, -to, ...?
2983 def copy(self):
2984 """Return a new PhotoImage with the same image as this widget."""
2985 destImage = PhotoImage()
2986 self.tk.call(destImage, 'copy', self.name)
2987 return destImage
2988 def zoom(self,x,y=''):
2989 """Return a new PhotoImage with the same image as this widget
2990 but zoom it with X and Y."""
2991 destImage = PhotoImage()
2992 if y=='': y=x
2993 self.tk.call(destImage, 'copy', self.name, '-zoom',x,y)
2994 return destImage
2995 def subsample(self,x,y=''):
2996 """Return a new PhotoImage based on the same image as this widget
2997 but use only every Xth or Yth pixel."""
2998 destImage = PhotoImage()
2999 if y=='': y=x
3000 self.tk.call(destImage, 'copy', self.name, '-subsample',x,y)
3001 return destImage
3002 def get(self, x, y):
3003 """Return the color (red, green, blue) of the pixel at X,Y."""
3004 return self.tk.call(self.name, 'get', x, y)
3005 def put(self, data, to=None):
3006 """Put row formated colors to image starting from
3007 position TO, e.g. image.put("{red green} {blue yellow}", to=(4,6))"""
3008 args = (self.name, 'put', data)
3009 if to:
3010 if to[0] == '-to':
3011 to = to[1:]
3012 args = args + ('-to',) + tuple(to)
3013 self.tk.call(args)
3014 # XXX read
3015 def write(self, filename, format=None, from_coords=None):
3016 """Write image to file FILENAME in FORMAT starting from
3017 position FROM_COORDS."""
3018 args = (self.name, 'write', filename)
3019 if format:
3020 args = args + ('-format', format)
3021 if from_coords:
3022 args = args + ('-from',) + tuple(from_coords)
3023 self.tk.call(args)
Guido van Rossum35f67fb1995-08-04 03:50:29 +00003024
3025class BitmapImage(Image):
Fredrik Lundh06d28152000-08-09 18:03:12 +00003026 """Widget which can display a bitmap."""
3027 def __init__(self, name=None, cnf={}, master=None, **kw):
3028 """Create a bitmap with NAME.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00003029
Fredrik Lundh06d28152000-08-09 18:03:12 +00003030 Valid resource names: background, data, file, foreground, maskdata, maskfile."""
3031 apply(Image.__init__, (self, 'bitmap', name, cnf, master), kw)
Guido van Rossum35f67fb1995-08-04 03:50:29 +00003032
3033def image_names(): return _default_root.tk.call('image', 'names')
3034def image_types(): return _default_root.tk.call('image', 'types')
3035
Guido van Rossumaec5dc91994-06-27 07:55:12 +00003036######################################################################
3037# Extensions:
3038
3039class Studbutton(Button):
Fredrik Lundh06d28152000-08-09 18:03:12 +00003040 def __init__(self, master=None, cnf={}, **kw):
3041 Widget.__init__(self, master, 'studbutton', cnf, kw)
3042 self.bind('<Any-Enter>', self.tkButtonEnter)
3043 self.bind('<Any-Leave>', self.tkButtonLeave)
3044 self.bind('<1>', self.tkButtonDown)
3045 self.bind('<ButtonRelease-1>', self.tkButtonUp)
Guido van Rossumaec5dc91994-06-27 07:55:12 +00003046
3047class Tributton(Button):
Fredrik Lundh06d28152000-08-09 18:03:12 +00003048 def __init__(self, master=None, cnf={}, **kw):
3049 Widget.__init__(self, master, 'tributton', cnf, kw)
3050 self.bind('<Any-Enter>', self.tkButtonEnter)
3051 self.bind('<Any-Leave>', self.tkButtonLeave)
3052 self.bind('<1>', self.tkButtonDown)
3053 self.bind('<ButtonRelease-1>', self.tkButtonUp)
3054 self['fg'] = self['bg']
3055 self['activebackground'] = self['bg']
Guido van Rossum37dcab11996-05-16 16:00:19 +00003056
Guido van Rossumc417ef81996-08-21 23:38:59 +00003057######################################################################
3058# Test:
3059
3060def _test():
Fredrik Lundh06d28152000-08-09 18:03:12 +00003061 root = Tk()
3062 text = "This is Tcl/Tk version %s" % TclVersion
3063 if TclVersion >= 8.1:
Fredrik Lundh8fffa202000-08-09 18:51:01 +00003064 try:
3065 text = text + unicode("\nThis should be a cedilla: \347",
3066 "iso-8859-1")
3067 except NameError:
3068 pass # no unicode support
Fredrik Lundh06d28152000-08-09 18:03:12 +00003069 label = Label(root, text=text)
3070 label.pack()
3071 test = Button(root, text="Click me!",
3072 command=lambda root=root: root.test.configure(
3073 text="[%s]" % root.test['text']))
3074 test.pack()
3075 root.test = test
3076 quit = Button(root, text="QUIT", command=root.destroy)
3077 quit.pack()
3078 # The following three commands are needed so the window pops
3079 # up on top on Windows...
3080 root.iconify()
3081 root.update()
3082 root.deiconify()
3083 root.mainloop()
Guido van Rossumc417ef81996-08-21 23:38:59 +00003084
3085if __name__ == '__main__':
Fredrik Lundh06d28152000-08-09 18:03:12 +00003086 _test()