blob: 4f8e479e0dc73950d7bac86d4e72c7a313be1eeb [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 Rossum37dcab11996-05-16 16:00:19 +000040import string; _string = string; del string
Guido van Rossumf0c891a1998-04-29 21:43:36 +000041try:
Fredrik Lundh06d28152000-08-09 18:03:12 +000042 import MacOS; _MacOS = MacOS; del MacOS
Guido van Rossumf0c891a1998-04-29 21:43:36 +000043except ImportError:
Fredrik Lundh06d28152000-08-09 18:03:12 +000044 _MacOS = None
Guido van Rossum18468821994-06-20 07:49:28 +000045
Guido van Rossum95806091997-02-15 18:33:24 +000046TkVersion = _string.atof(_tkinter.TK_VERSION)
47TclVersion = _string.atof(_tkinter.TCL_VERSION)
Guido van Rossum18468821994-06-20 07:49:28 +000048
Guido van Rossumd6615ab1997-08-05 02:35:01 +000049READABLE = _tkinter.READABLE
50WRITABLE = _tkinter.WRITABLE
51EXCEPTION = _tkinter.EXCEPTION
Guido van Rossumf53c86c1997-08-14 14:15:54 +000052
53# These are not always defined, e.g. not on Win32 with Tk 8.0 :-(
54try: _tkinter.createfilehandler
55except AttributeError: _tkinter.createfilehandler = None
56try: _tkinter.deletefilehandler
57except AttributeError: _tkinter.deletefilehandler = None
Fredrik Lundh06d28152000-08-09 18:03:12 +000058
59
Guido van Rossum2dcf5291994-07-06 09:23:20 +000060def _flatten(tuple):
Fredrik Lundh06d28152000-08-09 18:03:12 +000061 """Internal function."""
62 res = ()
63 for item in tuple:
64 if type(item) in (TupleType, ListType):
65 res = res + _flatten(item)
66 elif item is not None:
67 res = res + (item,)
68 return res
Guido van Rossum2dcf5291994-07-06 09:23:20 +000069
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +000070try: _flatten = _tkinter._flatten
71except AttributeError: pass
72
Guido van Rossum2dcf5291994-07-06 09:23:20 +000073def _cnfmerge(cnfs):
Fredrik Lundh06d28152000-08-09 18:03:12 +000074 """Internal function."""
75 if type(cnfs) is DictionaryType:
76 return cnfs
77 elif type(cnfs) in (NoneType, StringType):
78 return cnfs
79 else:
80 cnf = {}
81 for c in _flatten(cnfs):
82 try:
83 cnf.update(c)
84 except (AttributeError, TypeError), msg:
85 print "_cnfmerge: fallback due to:", msg
86 for k, v in c.items():
87 cnf[k] = v
88 return cnf
Guido van Rossum2dcf5291994-07-06 09:23:20 +000089
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +000090try: _cnfmerge = _tkinter._cnfmerge
91except AttributeError: pass
92
Guido van Rossum2dcf5291994-07-06 09:23:20 +000093class Event:
Fredrik Lundh06d28152000-08-09 18:03:12 +000094 """Container for the properties of an event.
Guido van Rossum5917ecb2000-06-29 16:30:50 +000095
Fredrik Lundh06d28152000-08-09 18:03:12 +000096 Instances of this type are generated if one of the following events occurs:
Guido van Rossum5917ecb2000-06-29 16:30:50 +000097
Fredrik Lundh06d28152000-08-09 18:03:12 +000098 KeyPress, KeyRelease - for keyboard events
99 ButtonPress, ButtonRelease, Motion, Enter, Leave, MouseWheel - for mouse events
100 Visibility, Unmap, Map, Expose, FocusIn, FocusOut, Circulate,
101 Colormap, Gravity, Reparent, Property, Destroy, Activate,
102 Deactivate - for window events.
103
104 If a callback function for one of these events is registered
105 using bind, bind_all, bind_class, or tag_bind, the callback is
106 called with an Event as first argument. It will have the
107 following attributes (in braces are the event types for which
108 the attribute is valid):
109
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000110 serial - serial number of event
Fredrik Lundh06d28152000-08-09 18:03:12 +0000111 num - mouse button pressed (ButtonPress, ButtonRelease)
112 focus - whether the window has the focus (Enter, Leave)
113 height - height of the exposed window (Configure, Expose)
114 width - width of the exposed window (Configure, Expose)
115 keycode - keycode of the pressed key (KeyPress, KeyRelease)
116 state - state of the event as a number (ButtonPress, ButtonRelease,
117 Enter, KeyPress, KeyRelease,
118 Leave, Motion)
119 state - state as a string (Visibility)
120 time - when the event occurred
121 x - x-position of the mouse
122 y - y-position of the mouse
123 x_root - x-position of the mouse on the screen
124 (ButtonPress, ButtonRelease, KeyPress, KeyRelease, Motion)
125 y_root - y-position of the mouse on the screen
126 (ButtonPress, ButtonRelease, KeyPress, KeyRelease, Motion)
127 char - pressed character (KeyPress, KeyRelease)
128 send_event - see X/Windows documentation
129 keysym - keysym of the the event as a string (KeyPress, KeyRelease)
130 keysym_num - keysym of the event as a number (KeyPress, KeyRelease)
131 type - type of the event as a number
132 widget - widget in which the event occurred
133 delta - delta of wheel movement (MouseWheel)
134 """
135 pass
Guido van Rossum2dcf5291994-07-06 09:23:20 +0000136
Guido van Rossumc4570481998-03-20 20:45:49 +0000137_support_default_root = 1
Guido van Rossumaec5dc91994-06-27 07:55:12 +0000138_default_root = None
139
Guido van Rossumc4570481998-03-20 20:45:49 +0000140def NoDefaultRoot():
Fredrik Lundh06d28152000-08-09 18:03:12 +0000141 """Inhibit setting of default root window.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000142
Fredrik Lundh06d28152000-08-09 18:03:12 +0000143 Call this function to inhibit that the first instance of
144 Tk is used for windows without an explicit parent window.
145 """
146 global _support_default_root
147 _support_default_root = 0
148 global _default_root
149 _default_root = None
150 del _default_root
Guido van Rossumc4570481998-03-20 20:45:49 +0000151
Guido van Rossum45853db1994-06-20 12:19:19 +0000152def _tkerror(err):
Fredrik Lundh06d28152000-08-09 18:03:12 +0000153 """Internal function."""
154 pass
Guido van Rossum18468821994-06-20 07:49:28 +0000155
Guido van Rossum97aeca11994-07-07 13:12:12 +0000156def _exit(code='0'):
Fredrik Lundh06d28152000-08-09 18:03:12 +0000157 """Internal function. Calling it will throw the exception SystemExit."""
158 raise SystemExit, code
Guido van Rossum97aeca11994-07-07 13:12:12 +0000159
Guido van Rossumaec5dc91994-06-27 07:55:12 +0000160_varnum = 0
161class Variable:
Fredrik Lundh06d28152000-08-09 18:03:12 +0000162 """Internal class. Base class to define value holders for e.g. buttons."""
163 _default = ""
164 def __init__(self, master=None):
165 """Construct a variable with an optional MASTER as master widget.
166 The variable is named PY_VAR_number in Tcl.
167 """
168 global _varnum
169 if not master:
170 master = _default_root
171 self._master = master
172 self._tk = master.tk
173 self._name = 'PY_VAR' + `_varnum`
174 _varnum = _varnum + 1
175 self.set(self._default)
176 def __del__(self):
177 """Unset the variable in Tcl."""
178 self._tk.globalunsetvar(self._name)
179 def __str__(self):
180 """Return the name of the variable in Tcl."""
181 return self._name
182 def set(self, value):
183 """Set the variable to VALUE."""
184 return self._tk.globalsetvar(self._name, value)
185 def trace_variable(self, mode, callback):
186 """Define a trace callback for the variable.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000187
Fredrik Lundh06d28152000-08-09 18:03:12 +0000188 MODE is one of "r", "w", "u" for read, write, undefine.
189 CALLBACK must be a function which is called when
190 the variable is read, written or undefined.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000191
Fredrik Lundh06d28152000-08-09 18:03:12 +0000192 Return the name of the callback.
193 """
194 cbname = self._master._register(callback)
195 self._tk.call("trace", "variable", self._name, mode, cbname)
196 return cbname
197 trace = trace_variable
198 def trace_vdelete(self, mode, cbname):
199 """Delete the trace callback for a variable.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000200
Fredrik Lundh06d28152000-08-09 18:03:12 +0000201 MODE is one of "r", "w", "u" for read, write, undefine.
202 CBNAME is the name of the callback returned from trace_variable or trace.
203 """
204 self._tk.call("trace", "vdelete", self._name, mode, cbname)
205 self._master.deletecommand(cbname)
206 def trace_vinfo(self):
207 """Return all trace callback information."""
208 return map(self._tk.split, self._tk.splitlist(
209 self._tk.call("trace", "vinfo", self._name)))
Guido van Rossumaec5dc91994-06-27 07:55:12 +0000210
211class StringVar(Variable):
Fredrik Lundh06d28152000-08-09 18:03:12 +0000212 """Value holder for strings variables."""
213 _default = ""
214 def __init__(self, master=None):
215 """Construct a string variable.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000216
Fredrik Lundh06d28152000-08-09 18:03:12 +0000217 MASTER can be given as master widget."""
218 Variable.__init__(self, master)
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000219
Fredrik Lundh06d28152000-08-09 18:03:12 +0000220 def get(self):
221 """Return value of variable as string."""
222 return self._tk.globalgetvar(self._name)
Guido van Rossumaec5dc91994-06-27 07:55:12 +0000223
224class IntVar(Variable):
Fredrik Lundh06d28152000-08-09 18:03:12 +0000225 """Value holder for integer variables."""
226 _default = 0
227 def __init__(self, master=None):
228 """Construct an integer variable.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000229
Fredrik Lundh06d28152000-08-09 18:03:12 +0000230 MASTER can be given as master widget."""
231 Variable.__init__(self, master)
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000232
Fredrik Lundh06d28152000-08-09 18:03:12 +0000233 def get(self):
234 """Return the value of the variable as an integer."""
235 return getint(self._tk.globalgetvar(self._name))
Guido van Rossumaec5dc91994-06-27 07:55:12 +0000236
237class DoubleVar(Variable):
Fredrik Lundh06d28152000-08-09 18:03:12 +0000238 """Value holder for float variables."""
239 _default = 0.0
240 def __init__(self, master=None):
241 """Construct a float variable.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000242
Fredrik Lundh06d28152000-08-09 18:03:12 +0000243 MASTER can be given as a master widget."""
244 Variable.__init__(self, master)
245
246 def get(self):
247 """Return the value of the variable as a float."""
248 return getdouble(self._tk.globalgetvar(self._name))
Guido van Rossumaec5dc91994-06-27 07:55:12 +0000249
250class BooleanVar(Variable):
Fredrik Lundh06d28152000-08-09 18:03:12 +0000251 """Value holder for boolean variables."""
252 _default = "false"
253 def __init__(self, master=None):
254 """Construct a boolean variable.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000255
Fredrik Lundh06d28152000-08-09 18:03:12 +0000256 MASTER can be given as a master widget."""
257 Variable.__init__(self, master)
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000258
Fredrik Lundh06d28152000-08-09 18:03:12 +0000259 def get(self):
260 """Return the value of the variable as 0 or 1."""
261 return self._tk.getboolean(self._tk.globalgetvar(self._name))
Guido van Rossumaec5dc91994-06-27 07:55:12 +0000262
Guido van Rossum35f67fb1995-08-04 03:50:29 +0000263def mainloop(n=0):
Fredrik Lundh06d28152000-08-09 18:03:12 +0000264 """Run the main loop of Tcl."""
265 _default_root.tk.mainloop(n)
Guido van Rossum2dcf5291994-07-06 09:23:20 +0000266
Guido van Rossum0132f691998-04-30 17:50:36 +0000267getint = int
Guido van Rossum2dcf5291994-07-06 09:23:20 +0000268
Guido van Rossum0132f691998-04-30 17:50:36 +0000269getdouble = float
Guido van Rossum2dcf5291994-07-06 09:23:20 +0000270
271def getboolean(s):
Fredrik Lundh06d28152000-08-09 18:03:12 +0000272 """Convert true and false to integer values 1 and 0."""
273 return _default_root.tk.getboolean(s)
Guido van Rossum2dcf5291994-07-06 09:23:20 +0000274
Guido van Rossum368e06b1997-11-07 20:38:49 +0000275# Methods defined on both toplevel and interior widgets
Guido van Rossum18468821994-06-20 07:49:28 +0000276class Misc:
Fredrik Lundh06d28152000-08-09 18:03:12 +0000277 """Internal class.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000278
Fredrik Lundh06d28152000-08-09 18:03:12 +0000279 Base class which defines methods common for interior widgets."""
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000280
Fredrik Lundh06d28152000-08-09 18:03:12 +0000281 # XXX font command?
282 _tclCommands = None
283 def destroy(self):
284 """Internal function.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000285
Fredrik Lundh06d28152000-08-09 18:03:12 +0000286 Delete all Tcl commands created for
287 this widget in the Tcl interpreter."""
288 if self._tclCommands is not None:
289 for name in self._tclCommands:
290 #print '- Tkinter: deleted command', name
291 self.tk.deletecommand(name)
292 self._tclCommands = None
293 def deletecommand(self, name):
294 """Internal function.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000295
Fredrik Lundh06d28152000-08-09 18:03:12 +0000296 Delete the Tcl command provided in NAME."""
297 #print '- Tkinter: deleted command', name
298 self.tk.deletecommand(name)
299 try:
300 self._tclCommands.remove(name)
301 except ValueError:
302 pass
303 def tk_strictMotif(self, boolean=None):
304 """Set Tcl internal variable, whether the look and feel
305 should adhere to Motif.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000306
Fredrik Lundh06d28152000-08-09 18:03:12 +0000307 A parameter of 1 means adhere to Motif (e.g. no color
308 change if mouse passes over slider).
309 Returns the set value."""
310 return self.tk.getboolean(self.tk.call(
311 'set', 'tk_strictMotif', boolean))
312 def tk_bisque(self):
313 """Change the color scheme to light brown as used in Tk 3.6 and before."""
314 self.tk.call('tk_bisque')
315 def tk_setPalette(self, *args, **kw):
316 """Set a new color scheme for all widget elements.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000317
Fredrik Lundh06d28152000-08-09 18:03:12 +0000318 A single color as argument will cause that all colors of Tk
319 widget elements are derived from this.
320 Alternatively several keyword parameters and its associated
321 colors can be given. The following keywords are valid:
322 activeBackground, foreground, selectColor,
323 activeForeground, highlightBackground, selectBackground,
324 background, highlightColor, selectForeground,
325 disabledForeground, insertBackground, troughColor."""
326 self.tk.call(('tk_setPalette',)
327 + _flatten(args) + _flatten(kw.items()))
328 def tk_menuBar(self, *args):
329 """Do not use. Needed in Tk 3.6 and earlier."""
330 pass # obsolete since Tk 4.0
331 def wait_variable(self, name='PY_VAR'):
332 """Wait until the variable is modified.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000333
Fredrik Lundh06d28152000-08-09 18:03:12 +0000334 A parameter of type IntVar, StringVar, DoubleVar or
335 BooleanVar must be given."""
336 self.tk.call('tkwait', 'variable', name)
337 waitvar = wait_variable # XXX b/w compat
338 def wait_window(self, window=None):
339 """Wait until a WIDGET is destroyed.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000340
Fredrik Lundh06d28152000-08-09 18:03:12 +0000341 If no parameter is given self is used."""
342 if window == None:
343 window = self
344 self.tk.call('tkwait', 'window', window._w)
345 def wait_visibility(self, window=None):
346 """Wait until the visibility of a WIDGET changes
347 (e.g. it appears).
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000348
Fredrik Lundh06d28152000-08-09 18:03:12 +0000349 If no parameter is given self is used."""
350 if window == None:
351 window = self
352 self.tk.call('tkwait', 'visibility', window._w)
353 def setvar(self, name='PY_VAR', value='1'):
354 """Set Tcl variable NAME to VALUE."""
355 self.tk.setvar(name, value)
356 def getvar(self, name='PY_VAR'):
357 """Return value of Tcl variable NAME."""
358 return self.tk.getvar(name)
359 getint = int
360 getdouble = float
361 def getboolean(self, s):
362 """Return 0 or 1 for Tcl boolean values true and false given as parameter."""
363 return self.tk.getboolean(s)
364 def focus_set(self):
365 """Direct input focus to this widget.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000366
Fredrik Lundh06d28152000-08-09 18:03:12 +0000367 If the application currently does not have the focus
368 this widget will get the focus if the application gets
369 the focus through the window manager."""
370 self.tk.call('focus', self._w)
371 focus = focus_set # XXX b/w compat?
372 def focus_force(self):
373 """Direct input focus to this widget even if the
374 application does not have the focus. Use with
375 caution!"""
376 self.tk.call('focus', '-force', self._w)
377 def focus_get(self):
378 """Return the widget which has currently the focus in the
379 application.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000380
Fredrik Lundh06d28152000-08-09 18:03:12 +0000381 Use focus_displayof to allow working with several
382 displays. Return None if application does not have
383 the focus."""
384 name = self.tk.call('focus')
385 if name == 'none' or not name: return None
386 return self._nametowidget(name)
387 def focus_displayof(self):
388 """Return the widget which has currently the focus on the
389 display where this widget is located.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000390
Fredrik Lundh06d28152000-08-09 18:03:12 +0000391 Return None if the application does not have the focus."""
392 name = self.tk.call('focus', '-displayof', self._w)
393 if name == 'none' or not name: return None
394 return self._nametowidget(name)
395 def focus_lastfor(self):
396 """Return the widget which would have the focus if top level
397 for this widget gets the focus from the window manager."""
398 name = self.tk.call('focus', '-lastfor', self._w)
399 if name == 'none' or not name: return None
400 return self._nametowidget(name)
401 def tk_focusFollowsMouse(self):
402 """The widget under mouse will get automatically focus. Can not
403 be disabled easily."""
404 self.tk.call('tk_focusFollowsMouse')
405 def tk_focusNext(self):
406 """Return the next widget in the focus order which follows
407 widget which has currently the focus.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000408
Fredrik Lundh06d28152000-08-09 18:03:12 +0000409 The focus order first goes to the next child, then to
410 the children of the child recursively and then to the
411 next sibling which is higher in the stacking order. A
412 widget is omitted if it has the takefocus resource set
413 to 0."""
414 name = self.tk.call('tk_focusNext', self._w)
415 if not name: return None
416 return self._nametowidget(name)
417 def tk_focusPrev(self):
418 """Return previous widget in the focus order. See tk_focusNext for details."""
419 name = self.tk.call('tk_focusPrev', self._w)
420 if not name: return None
421 return self._nametowidget(name)
422 def after(self, ms, func=None, *args):
423 """Call function once after given time.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000424
Fredrik Lundh06d28152000-08-09 18:03:12 +0000425 MS specifies the time in milliseconds. FUNC gives the
426 function which shall be called. Additional parameters
427 are given as parameters to the function call. Return
428 identifier to cancel scheduling with after_cancel."""
429 if not func:
430 # I'd rather use time.sleep(ms*0.001)
431 self.tk.call('after', ms)
432 else:
433 # XXX Disgusting hack to clean up after calling func
434 tmp = []
435 def callit(func=func, args=args, self=self, tmp=tmp):
436 try:
437 apply(func, args)
438 finally:
439 try:
440 self.deletecommand(tmp[0])
441 except TclError:
442 pass
443 name = self._register(callit)
444 tmp.append(name)
445 return self.tk.call('after', ms, name)
446 def after_idle(self, func, *args):
447 """Call FUNC once if the Tcl main loop has no event to
448 process.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000449
Fredrik Lundh06d28152000-08-09 18:03:12 +0000450 Return an identifier to cancel the scheduling with
451 after_cancel."""
452 return apply(self.after, ('idle', func) + args)
453 def after_cancel(self, id):
454 """Cancel scheduling of function identified with ID.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000455
Fredrik Lundh06d28152000-08-09 18:03:12 +0000456 Identifier returned by after or after_idle must be
457 given as first parameter."""
458 self.tk.call('after', 'cancel', id)
459 def bell(self, displayof=0):
460 """Ring a display's bell."""
461 self.tk.call(('bell',) + self._displayof(displayof))
462 # Clipboard handling:
463 def clipboard_clear(self, **kw):
464 """Clear the data in the Tk clipboard.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000465
Fredrik Lundh06d28152000-08-09 18:03:12 +0000466 A widget specified for the optional displayof keyword
467 argument specifies the target display."""
468 if not kw.has_key('displayof'): kw['displayof'] = self._w
469 self.tk.call(('clipboard', 'clear') + self._options(kw))
470 def clipboard_append(self, string, **kw):
471 """Append STRING to the Tk clipboard.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000472
Fredrik Lundh06d28152000-08-09 18:03:12 +0000473 A widget specified at the optional displayof keyword
474 argument specifies the target display. The clipboard
475 can be retrieved with selection_get."""
476 if not kw.has_key('displayof'): kw['displayof'] = self._w
477 self.tk.call(('clipboard', 'append') + self._options(kw)
478 + ('--', string))
479 # XXX grab current w/o window argument
480 def grab_current(self):
481 """Return widget which has currently the grab in this application
482 or None."""
483 name = self.tk.call('grab', 'current', self._w)
484 if not name: return None
485 return self._nametowidget(name)
486 def grab_release(self):
487 """Release grab for this widget if currently set."""
488 self.tk.call('grab', 'release', self._w)
489 def grab_set(self):
490 """Set grab for this widget.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000491
Fredrik Lundh06d28152000-08-09 18:03:12 +0000492 A grab directs all events to this and descendant
493 widgets in the application."""
494 self.tk.call('grab', 'set', self._w)
495 def grab_set_global(self):
496 """Set global grab for this widget.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000497
Fredrik Lundh06d28152000-08-09 18:03:12 +0000498 A global grab directs all events to this and
499 descendant widgets on the display. Use with caution -
500 other applications do not get events anymore."""
501 self.tk.call('grab', 'set', '-global', self._w)
502 def grab_status(self):
503 """Return None, "local" or "global" if this widget has
504 no, a local or a global grab."""
505 status = self.tk.call('grab', 'status', self._w)
506 if status == 'none': status = None
507 return status
508 def lower(self, belowThis=None):
509 """Lower this widget in the stacking order."""
510 self.tk.call('lower', self._w, belowThis)
511 def option_add(self, pattern, value, priority = None):
512 """Set a VALUE (second parameter) for an option
513 PATTERN (first parameter).
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000514
Fredrik Lundh06d28152000-08-09 18:03:12 +0000515 An optional third parameter gives the numeric priority
516 (defaults to 80)."""
517 self.tk.call('option', 'add', pattern, value, priority)
518 def option_clear(self):
519 """Clear the option database.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000520
Fredrik Lundh06d28152000-08-09 18:03:12 +0000521 It will be reloaded if option_add is called."""
522 self.tk.call('option', 'clear')
523 def option_get(self, name, className):
524 """Return the value for an option NAME for this widget
525 with CLASSNAME.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000526
Fredrik Lundh06d28152000-08-09 18:03:12 +0000527 Values with higher priority override lower values."""
528 return self.tk.call('option', 'get', self._w, name, className)
529 def option_readfile(self, fileName, priority = None):
530 """Read file FILENAME into the option database.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000531
Fredrik Lundh06d28152000-08-09 18:03:12 +0000532 An optional second parameter gives the numeric
533 priority."""
534 self.tk.call('option', 'readfile', fileName, priority)
535 def selection_clear(self, **kw):
536 """Clear the current X selection."""
537 if not kw.has_key('displayof'): kw['displayof'] = self._w
538 self.tk.call(('selection', 'clear') + self._options(kw))
539 def selection_get(self, **kw):
540 """Return the contents of the current X selection.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000541
Fredrik Lundh06d28152000-08-09 18:03:12 +0000542 A keyword parameter selection specifies the name of
543 the selection and defaults to PRIMARY. A keyword
544 parameter displayof specifies a widget on the display
545 to use."""
546 if not kw.has_key('displayof'): kw['displayof'] = self._w
547 return self.tk.call(('selection', 'get') + self._options(kw))
548 def selection_handle(self, command, **kw):
549 """Specify a function COMMAND to call if the X
550 selection owned by this widget is queried by another
551 application.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000552
Fredrik Lundh06d28152000-08-09 18:03:12 +0000553 This function must return the contents of the
554 selection. The function will be called with the
555 arguments OFFSET and LENGTH which allows the chunking
556 of very long selections. The following keyword
557 parameters can be provided:
558 selection - name of the selection (default PRIMARY),
559 type - type of the selection (e.g. STRING, FILE_NAME)."""
560 name = self._register(command)
561 self.tk.call(('selection', 'handle') + self._options(kw)
562 + (self._w, name))
563 def selection_own(self, **kw):
564 """Become owner of X selection.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000565
Fredrik Lundh06d28152000-08-09 18:03:12 +0000566 A keyword parameter selection specifies the name of
567 the selection (default PRIMARY)."""
568 self.tk.call(('selection', 'own') +
569 self._options(kw) + (self._w,))
570 def selection_own_get(self, **kw):
571 """Return owner of X selection.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000572
Fredrik Lundh06d28152000-08-09 18:03:12 +0000573 The following keyword parameter can
574 be provided:
575 selection - name of the selection (default PRIMARY),
576 type - type of the selection (e.g. STRING, FILE_NAME)."""
577 if not kw.has_key('displayof'): kw['displayof'] = self._w
578 name = self.tk.call(('selection', 'own') + self._options(kw))
579 if not name: return None
580 return self._nametowidget(name)
581 def send(self, interp, cmd, *args):
582 """Send Tcl command CMD to different interpreter INTERP to be executed."""
583 return self.tk.call(('send', interp, cmd) + args)
584 def lower(self, belowThis=None):
585 """Lower this widget in the stacking order."""
586 self.tk.call('lower', self._w, belowThis)
587 def tkraise(self, aboveThis=None):
588 """Raise this widget in the stacking order."""
589 self.tk.call('raise', self._w, aboveThis)
590 lift = tkraise
591 def colormodel(self, value=None):
592 """Useless. Not implemented in Tk."""
593 return self.tk.call('tk', 'colormodel', self._w, value)
594 def winfo_atom(self, name, displayof=0):
595 """Return integer which represents atom NAME."""
596 args = ('winfo', 'atom') + self._displayof(displayof) + (name,)
597 return getint(self.tk.call(args))
598 def winfo_atomname(self, id, displayof=0):
599 """Return name of atom with identifier ID."""
600 args = ('winfo', 'atomname') \
601 + self._displayof(displayof) + (id,)
602 return self.tk.call(args)
603 def winfo_cells(self):
604 """Return number of cells in the colormap for this widget."""
605 return getint(
606 self.tk.call('winfo', 'cells', self._w))
607 def winfo_children(self):
608 """Return a list of all widgets which are children of this widget."""
609 return map(self._nametowidget,
610 self.tk.splitlist(self.tk.call(
611 'winfo', 'children', self._w)))
612 def winfo_class(self):
613 """Return window class name of this widget."""
614 return self.tk.call('winfo', 'class', self._w)
615 def winfo_colormapfull(self):
616 """Return true if at the last color request the colormap was full."""
617 return self.tk.getboolean(
618 self.tk.call('winfo', 'colormapfull', self._w))
619 def winfo_containing(self, rootX, rootY, displayof=0):
620 """Return the widget which is at the root coordinates ROOTX, ROOTY."""
621 args = ('winfo', 'containing') \
622 + self._displayof(displayof) + (rootX, rootY)
623 name = self.tk.call(args)
624 if not name: return None
625 return self._nametowidget(name)
626 def winfo_depth(self):
627 """Return the number of bits per pixel."""
628 return getint(self.tk.call('winfo', 'depth', self._w))
629 def winfo_exists(self):
630 """Return true if this widget exists."""
631 return getint(
632 self.tk.call('winfo', 'exists', self._w))
633 def winfo_fpixels(self, number):
634 """Return the number of pixels for the given distance NUMBER
635 (e.g. "3c") as float."""
636 return getdouble(self.tk.call(
637 'winfo', 'fpixels', self._w, number))
638 def winfo_geometry(self):
639 """Return geometry string for this widget in the form "widthxheight+X+Y"."""
640 return self.tk.call('winfo', 'geometry', self._w)
641 def winfo_height(self):
642 """Return height of this widget."""
643 return getint(
644 self.tk.call('winfo', 'height', self._w))
645 def winfo_id(self):
646 """Return identifier ID for this widget."""
647 return self.tk.getint(
648 self.tk.call('winfo', 'id', self._w))
649 def winfo_interps(self, displayof=0):
650 """Return the name of all Tcl interpreters for this display."""
651 args = ('winfo', 'interps') + self._displayof(displayof)
652 return self.tk.splitlist(self.tk.call(args))
653 def winfo_ismapped(self):
654 """Return true if this widget is mapped."""
655 return getint(
656 self.tk.call('winfo', 'ismapped', self._w))
657 def winfo_manager(self):
658 """Return the window mananger name for this widget."""
659 return self.tk.call('winfo', 'manager', self._w)
660 def winfo_name(self):
661 """Return the name of this widget."""
662 return self.tk.call('winfo', 'name', self._w)
663 def winfo_parent(self):
664 """Return the name of the parent of this widget."""
665 return self.tk.call('winfo', 'parent', self._w)
666 def winfo_pathname(self, id, displayof=0):
667 """Return the pathname of the widget given by ID."""
668 args = ('winfo', 'pathname') \
669 + self._displayof(displayof) + (id,)
670 return self.tk.call(args)
671 def winfo_pixels(self, number):
672 """Rounded integer value of winfo_fpixels."""
673 return getint(
674 self.tk.call('winfo', 'pixels', self._w, number))
675 def winfo_pointerx(self):
676 """Return the x coordinate of the pointer on the root window."""
677 return getint(
678 self.tk.call('winfo', 'pointerx', self._w))
679 def winfo_pointerxy(self):
680 """Return a tuple of x and y coordinates of the pointer on the root window."""
681 return self._getints(
682 self.tk.call('winfo', 'pointerxy', self._w))
683 def winfo_pointery(self):
684 """Return the y coordinate of the pointer on the root window."""
685 return getint(
686 self.tk.call('winfo', 'pointery', self._w))
687 def winfo_reqheight(self):
688 """Return requested height of this widget."""
689 return getint(
690 self.tk.call('winfo', 'reqheight', self._w))
691 def winfo_reqwidth(self):
692 """Return requested width of this widget."""
693 return getint(
694 self.tk.call('winfo', 'reqwidth', self._w))
695 def winfo_rgb(self, color):
696 """Return tuple of decimal values for red, green, blue for
697 COLOR in this widget."""
698 return self._getints(
699 self.tk.call('winfo', 'rgb', self._w, color))
700 def winfo_rootx(self):
701 """Return x coordinate of upper left corner of this widget on the
702 root window."""
703 return getint(
704 self.tk.call('winfo', 'rootx', self._w))
705 def winfo_rooty(self):
706 """Return y coordinate of upper left corner of this widget on the
707 root window."""
708 return getint(
709 self.tk.call('winfo', 'rooty', self._w))
710 def winfo_screen(self):
711 """Return the screen name of this widget."""
712 return self.tk.call('winfo', 'screen', self._w)
713 def winfo_screencells(self):
714 """Return the number of the cells in the colormap of the screen
715 of this widget."""
716 return getint(
717 self.tk.call('winfo', 'screencells', self._w))
718 def winfo_screendepth(self):
719 """Return the number of bits per pixel of the root window of the
720 screen of this widget."""
721 return getint(
722 self.tk.call('winfo', 'screendepth', self._w))
723 def winfo_screenheight(self):
724 """Return the number of pixels of the height of the screen of this widget
725 in pixel."""
726 return getint(
727 self.tk.call('winfo', 'screenheight', self._w))
728 def winfo_screenmmheight(self):
729 """Return the number of pixels of the height of the screen of
730 this widget in mm."""
731 return getint(
732 self.tk.call('winfo', 'screenmmheight', self._w))
733 def winfo_screenmmwidth(self):
734 """Return the number of pixels of the width of the screen of
735 this widget in mm."""
736 return getint(
737 self.tk.call('winfo', 'screenmmwidth', self._w))
738 def winfo_screenvisual(self):
739 """Return one of the strings directcolor, grayscale, pseudocolor,
740 staticcolor, staticgray, or truecolor for the default
741 colormodel of this screen."""
742 return self.tk.call('winfo', 'screenvisual', self._w)
743 def winfo_screenwidth(self):
744 """Return the number of pixels of the width of the screen of
745 this widget in pixel."""
746 return getint(
747 self.tk.call('winfo', 'screenwidth', self._w))
748 def winfo_server(self):
749 """Return information of the X-Server of the screen of this widget in
750 the form "XmajorRminor vendor vendorVersion"."""
751 return self.tk.call('winfo', 'server', self._w)
752 def winfo_toplevel(self):
753 """Return the toplevel widget of this widget."""
754 return self._nametowidget(self.tk.call(
755 'winfo', 'toplevel', self._w))
756 def winfo_viewable(self):
757 """Return true if the widget and all its higher ancestors are mapped."""
758 return getint(
759 self.tk.call('winfo', 'viewable', self._w))
760 def winfo_visual(self):
761 """Return one of the strings directcolor, grayscale, pseudocolor,
762 staticcolor, staticgray, or truecolor for the
763 colormodel of this widget."""
764 return self.tk.call('winfo', 'visual', self._w)
765 def winfo_visualid(self):
766 """Return the X identifier for the visual for this widget."""
767 return self.tk.call('winfo', 'visualid', self._w)
768 def winfo_visualsavailable(self, includeids=0):
769 """Return a list of all visuals available for the screen
770 of this widget.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000771
Fredrik Lundh06d28152000-08-09 18:03:12 +0000772 Each item in the list consists of a visual name (see winfo_visual), a
773 depth and if INCLUDEIDS=1 is given also the X identifier."""
774 data = self.tk.split(
775 self.tk.call('winfo', 'visualsavailable', self._w,
776 includeids and 'includeids' or None))
777 return map(self.__winfo_parseitem, data)
778 def __winfo_parseitem(self, t):
779 """Internal function."""
780 return t[:1] + tuple(map(self.__winfo_getint, t[1:]))
781 def __winfo_getint(self, x):
782 """Internal function."""
783 return _string.atoi(x, 0)
784 def winfo_vrootheight(self):
785 """Return the height of the virtual root window associated with this
786 widget in pixels. If there is no virtual root window return the
787 height of the screen."""
788 return getint(
789 self.tk.call('winfo', 'vrootheight', self._w))
790 def winfo_vrootwidth(self):
791 """Return the width of the virtual root window associated with this
792 widget in pixel. If there is no virtual root window return the
793 width of the screen."""
794 return getint(
795 self.tk.call('winfo', 'vrootwidth', self._w))
796 def winfo_vrootx(self):
797 """Return the x offset of the virtual root relative to the root
798 window of the screen of this widget."""
799 return getint(
800 self.tk.call('winfo', 'vrootx', self._w))
801 def winfo_vrooty(self):
802 """Return the y offset of the virtual root relative to the root
803 window of the screen of this widget."""
804 return getint(
805 self.tk.call('winfo', 'vrooty', self._w))
806 def winfo_width(self):
807 """Return the width of this widget."""
808 return getint(
809 self.tk.call('winfo', 'width', self._w))
810 def winfo_x(self):
811 """Return the x coordinate of the upper left corner of this widget
812 in the parent."""
813 return getint(
814 self.tk.call('winfo', 'x', self._w))
815 def winfo_y(self):
816 """Return the y coordinate of the upper left corner of this widget
817 in the parent."""
818 return getint(
819 self.tk.call('winfo', 'y', self._w))
820 def update(self):
821 """Enter event loop until all pending events have been processed by Tcl."""
822 self.tk.call('update')
823 def update_idletasks(self):
824 """Enter event loop until all idle callbacks have been called. This
825 will update the display of windows but not process events caused by
826 the user."""
827 self.tk.call('update', 'idletasks')
828 def bindtags(self, tagList=None):
829 """Set or get the list of bindtags for this widget.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000830
Fredrik Lundh06d28152000-08-09 18:03:12 +0000831 With no argument return the list of all bindtags associated with
832 this widget. With a list of strings as argument the bindtags are
833 set to this list. The bindtags determine in which order events are
834 processed (see bind)."""
835 if tagList is None:
836 return self.tk.splitlist(
837 self.tk.call('bindtags', self._w))
838 else:
839 self.tk.call('bindtags', self._w, tagList)
840 def _bind(self, what, sequence, func, add, needcleanup=1):
841 """Internal function."""
842 if type(func) is StringType:
843 self.tk.call(what + (sequence, func))
844 elif func:
845 funcid = self._register(func, self._substitute,
846 needcleanup)
847 cmd = ('%sif {"[%s %s]" == "break"} break\n'
848 %
849 (add and '+' or '',
850 funcid,
851 _string.join(self._subst_format)))
852 self.tk.call(what + (sequence, cmd))
853 return funcid
854 elif sequence:
855 return self.tk.call(what + (sequence,))
856 else:
857 return self.tk.splitlist(self.tk.call(what))
858 def bind(self, sequence=None, func=None, add=None):
859 """Bind to this widget at event SEQUENCE a call to function FUNC.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000860
Fredrik Lundh06d28152000-08-09 18:03:12 +0000861 SEQUENCE is a string of concatenated event
862 patterns. An event pattern is of the form
863 <MODIFIER-MODIFIER-TYPE-DETAIL> where MODIFIER is one
864 of Control, Mod2, M2, Shift, Mod3, M3, Lock, Mod4, M4,
865 Button1, B1, Mod5, M5 Button2, B2, Meta, M, Button3,
866 B3, Alt, Button4, B4, Double, Button5, B5 Triple,
867 Mod1, M1. TYPE is one of Activate, Enter, Map,
868 ButtonPress, Button, Expose, Motion, ButtonRelease
869 FocusIn, MouseWheel, Circulate, FocusOut, Property,
870 Colormap, Gravity Reparent, Configure, KeyPress, Key,
871 Unmap, Deactivate, KeyRelease Visibility, Destroy,
872 Leave and DETAIL is the button number for ButtonPress,
873 ButtonRelease and DETAIL is the Keysym for KeyPress and
874 KeyRelease. Examples are
875 <Control-Button-1> for pressing Control and mouse button 1 or
876 <Alt-A> for pressing A and the Alt key (KeyPress can be omitted).
877 An event pattern can also be a virtual event of the form
878 <<AString>> where AString can be arbitrary. This
879 event can be generated by event_generate.
880 If events are concatenated they must appear shortly
881 after each other.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000882
Fredrik Lundh06d28152000-08-09 18:03:12 +0000883 FUNC will be called if the event sequence occurs with an
884 instance of Event as argument. If the return value of FUNC is
885 "break" no further bound function is invoked.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000886
Fredrik Lundh06d28152000-08-09 18:03:12 +0000887 An additional boolean parameter ADD specifies whether FUNC will
888 be called additionally to the other bound function or whether
889 it will replace the previous function.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000890
Fredrik Lundh06d28152000-08-09 18:03:12 +0000891 Bind will return an identifier to allow deletion of the bound function with
892 unbind without memory leak.
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000893
Fredrik Lundh06d28152000-08-09 18:03:12 +0000894 If FUNC or SEQUENCE is omitted the bound function or list
895 of bound events are returned."""
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000896
Fredrik Lundh06d28152000-08-09 18:03:12 +0000897 return self._bind(('bind', self._w), sequence, func, add)
898 def unbind(self, sequence, funcid=None):
899 """Unbind for this widget for event SEQUENCE the
900 function identified with FUNCID."""
901 self.tk.call('bind', self._w, sequence, '')
902 if funcid:
903 self.deletecommand(funcid)
904 def bind_all(self, sequence=None, func=None, add=None):
905 """Bind to all widgets at an event SEQUENCE a call to function FUNC.
906 An additional boolean parameter ADD specifies whether FUNC will
907 be called additionally to the other bound function or whether
908 it will replace the previous function. See bind for the return value."""
909 return self._bind(('bind', 'all'), sequence, func, add, 0)
910 def unbind_all(self, sequence):
911 """Unbind for all widgets for event SEQUENCE all functions."""
912 self.tk.call('bind', 'all' , sequence, '')
913 def bind_class(self, className, sequence=None, func=None, add=None):
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000914
Fredrik Lundh06d28152000-08-09 18:03:12 +0000915 """Bind to widgets with bindtag CLASSNAME at event
916 SEQUENCE a call of function FUNC. An additional
917 boolean parameter ADD specifies whether FUNC will be
918 called additionally to the other bound function or
919 whether it will replace the previous function. See bind for
920 the return value."""
Guido van Rossum5917ecb2000-06-29 16:30:50 +0000921
Fredrik Lundh06d28152000-08-09 18:03:12 +0000922 return self._bind(('bind', className), sequence, func, add, 0)
923 def unbind_class(self, className, sequence):
924 """Unbind for a all widgets with bindtag CLASSNAME for event SEQUENCE
925 all functions."""
926 self.tk.call('bind', className , sequence, '')
927 def mainloop(self, n=0):
928 """Call the mainloop of Tk."""
929 self.tk.mainloop(n)
930 def quit(self):
931 """Quit the Tcl interpreter. All widgets will be destroyed."""
932 self.tk.quit()
933 def _getints(self, string):
934 """Internal function."""
935 if string:
936 return tuple(map(getint, self.tk.splitlist(string)))
937 def _getdoubles(self, string):
938 """Internal function."""
939 if string:
940 return tuple(map(getdouble, self.tk.splitlist(string)))
941 def _getboolean(self, string):
942 """Internal function."""
943 if string:
944 return self.tk.getboolean(string)
945 def _displayof(self, displayof):
946 """Internal function."""
947 if displayof:
948 return ('-displayof', displayof)
949 if displayof is None:
950 return ('-displayof', self._w)
951 return ()
952 def _options(self, cnf, kw = None):
953 """Internal function."""
954 if kw:
955 cnf = _cnfmerge((cnf, kw))
956 else:
957 cnf = _cnfmerge(cnf)
958 res = ()
959 for k, v in cnf.items():
960 if v is not None:
961 if k[-1] == '_': k = k[:-1]
962 if callable(v):
963 v = self._register(v)
964 res = res + ('-'+k, v)
965 return res
966 def nametowidget(self, name):
967 """Return the Tkinter instance of a widget identified by
968 its Tcl name NAME."""
969 w = self
970 if name[0] == '.':
971 w = w._root()
972 name = name[1:]
973 find = _string.find
974 while name:
975 i = find(name, '.')
976 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)
1051 e.delta = getint(D)
1052 return (e,)
1053 def _report_exception(self):
1054 """Internal function."""
1055 import sys
1056 exc, val, tb = sys.exc_type, sys.exc_value, sys.exc_traceback
1057 root = self._root()
1058 root.report_callback_exception(exc, val, tb)
1059 # These used to be defined in Widget:
1060 def configure(self, cnf=None, **kw):
1061 """Configure resources of a widget.
Barry Warsaw107e6231998-12-15 00:44:15 +00001062
Fredrik Lundh06d28152000-08-09 18:03:12 +00001063 The values for resources are specified as keyword
1064 arguments. To get an overview about
1065 the allowed keyword arguments call the method keys.
1066 """
1067 # XXX ought to generalize this so tag_config etc. can use it
1068 if kw:
1069 cnf = _cnfmerge((cnf, kw))
1070 elif cnf:
1071 cnf = _cnfmerge(cnf)
1072 if cnf is None:
1073 cnf = {}
1074 for x in self.tk.split(
1075 self.tk.call(self._w, 'configure')):
1076 cnf[x[0][1:]] = (x[0][1:],) + x[1:]
1077 return cnf
1078 if type(cnf) is StringType:
1079 x = self.tk.split(self.tk.call(
1080 self._w, 'configure', '-'+cnf))
1081 return (x[0][1:],) + x[1:]
1082 self.tk.call((self._w, 'configure')
1083 + self._options(cnf))
1084 config = configure
1085 def cget(self, key):
1086 """Return the resource value for a KEY given as string."""
1087 return self.tk.call(self._w, 'cget', '-' + key)
1088 __getitem__ = cget
1089 def __setitem__(self, key, value):
1090 self.configure({key: value})
1091 def keys(self):
1092 """Return a list of all resource names of this widget."""
1093 return map(lambda x: x[0][1:],
1094 self.tk.split(self.tk.call(self._w, 'configure')))
1095 def __str__(self):
1096 """Return the window path name of this widget."""
1097 return self._w
1098 # Pack methods that apply to the master
1099 _noarg_ = ['_noarg_']
1100 def pack_propagate(self, flag=_noarg_):
1101 """Set or get the status for propagation of geometry information.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001102
Fredrik Lundh06d28152000-08-09 18:03:12 +00001103 A boolean argument specifies whether the geometry information
1104 of the slaves will determine the size of this widget. If no argument
1105 is given the current setting will be returned.
1106 """
1107 if flag is Misc._noarg_:
1108 return self._getboolean(self.tk.call(
1109 'pack', 'propagate', self._w))
1110 else:
1111 self.tk.call('pack', 'propagate', self._w, flag)
1112 propagate = pack_propagate
1113 def pack_slaves(self):
1114 """Return a list of all slaves of this widget
1115 in its packing order."""
1116 return map(self._nametowidget,
1117 self.tk.splitlist(
1118 self.tk.call('pack', 'slaves', self._w)))
1119 slaves = pack_slaves
1120 # Place method that applies to the master
1121 def place_slaves(self):
1122 """Return a list of all slaves of this widget
1123 in its packing order."""
1124 return map(self._nametowidget,
1125 self.tk.splitlist(
1126 self.tk.call(
1127 'place', 'slaves', self._w)))
1128 # Grid methods that apply to the master
1129 def grid_bbox(self, column=None, row=None, col2=None, row2=None):
1130 """Return a tuple of integer coordinates for the bounding
1131 box of this widget controlled by the geometry manager grid.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001132
Fredrik Lundh06d28152000-08-09 18:03:12 +00001133 If COLUMN, ROW is given the bounding box applies from
1134 the cell with row and column 0 to the specified
1135 cell. If COL2 and ROW2 are given the bounding box
1136 starts at that cell.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001137
Fredrik Lundh06d28152000-08-09 18:03:12 +00001138 The returned integers specify the offset of the upper left
1139 corner in the master widget and the width and height.
1140 """
1141 args = ('grid', 'bbox', self._w)
1142 if column is not None and row is not None:
1143 args = args + (column, row)
1144 if col2 is not None and row2 is not None:
1145 args = args + (col2, row2)
1146 return self._getints(apply(self.tk.call, args)) or None
Guido van Rossum18468821994-06-20 07:49:28 +00001147
Fredrik Lundh06d28152000-08-09 18:03:12 +00001148 bbox = grid_bbox
1149 def _grid_configure(self, command, index, cnf, kw):
1150 """Internal function."""
1151 if type(cnf) is StringType and not kw:
1152 if cnf[-1:] == '_':
1153 cnf = cnf[:-1]
1154 if cnf[:1] != '-':
1155 cnf = '-'+cnf
1156 options = (cnf,)
1157 else:
1158 options = self._options(cnf, kw)
1159 if not options:
1160 res = self.tk.call('grid',
1161 command, self._w, index)
1162 words = self.tk.splitlist(res)
1163 dict = {}
1164 for i in range(0, len(words), 2):
1165 key = words[i][1:]
1166 value = words[i+1]
1167 if not value:
1168 value = None
1169 elif '.' in value:
1170 value = getdouble(value)
1171 else:
1172 value = getint(value)
1173 dict[key] = value
1174 return dict
1175 res = self.tk.call(
1176 ('grid', command, self._w, index)
1177 + options)
1178 if len(options) == 1:
1179 if not res: return None
1180 # In Tk 7.5, -width can be a float
1181 if '.' in res: return getdouble(res)
1182 return getint(res)
1183 def grid_columnconfigure(self, index, cnf={}, **kw):
1184 """Configure column INDEX of a grid.
Guido van Rossum80f8be81997-12-02 19:51:39 +00001185
Fredrik Lundh06d28152000-08-09 18:03:12 +00001186 Valid resources are minsize (minimum size of the column),
1187 weight (how much does additional space propagate to this column)
1188 and pad (how much space to let additionally)."""
1189 return self._grid_configure('columnconfigure', index, cnf, kw)
1190 columnconfigure = grid_columnconfigure
1191 def grid_propagate(self, flag=_noarg_):
1192 """Set or get the status for propagation of geometry information.
Guido van Rossum80f8be81997-12-02 19:51:39 +00001193
Fredrik Lundh06d28152000-08-09 18:03:12 +00001194 A boolean argument specifies whether the geometry information
1195 of the slaves will determine the size of this widget. If no argument
1196 is given, the current setting will be returned.
1197 """
1198 if flag is Misc._noarg_:
1199 return self._getboolean(self.tk.call(
1200 'grid', 'propagate', self._w))
1201 else:
1202 self.tk.call('grid', 'propagate', self._w, flag)
1203 def grid_rowconfigure(self, index, cnf={}, **kw):
1204 """Configure row INDEX of a grid.
Guido van Rossum80f8be81997-12-02 19:51:39 +00001205
Fredrik Lundh06d28152000-08-09 18:03:12 +00001206 Valid resources are minsize (minimum size of the row),
1207 weight (how much does additional space propagate to this row)
1208 and pad (how much space to let additionally)."""
1209 return self._grid_configure('rowconfigure', index, cnf, kw)
1210 rowconfigure = grid_rowconfigure
1211 def grid_size(self):
1212 """Return a tuple of the number of column and rows in the grid."""
1213 return self._getints(
1214 self.tk.call('grid', 'size', self._w)) or None
1215 size = grid_size
1216 def grid_slaves(self, row=None, column=None):
1217 """Return a list of all slaves of this widget
1218 in its packing order."""
1219 args = ()
1220 if row is not None:
1221 args = args + ('-row', row)
1222 if column is not None:
1223 args = args + ('-column', column)
1224 return map(self._nametowidget,
1225 self.tk.splitlist(self.tk.call(
1226 ('grid', 'slaves', self._w) + args)))
Guido van Rossum80f8be81997-12-02 19:51:39 +00001227
Fredrik Lundh06d28152000-08-09 18:03:12 +00001228 # Support for the "event" command, new in Tk 4.2.
1229 # By Case Roole.
Guido van Rossum80f8be81997-12-02 19:51:39 +00001230
Fredrik Lundh06d28152000-08-09 18:03:12 +00001231 def event_add(self, virtual, *sequences):
1232 """Bind a virtual event VIRTUAL (of the form <<Name>>)
1233 to an event SEQUENCE such that the virtual event is triggered
1234 whenever SEQUENCE occurs."""
1235 args = ('event', 'add', virtual) + sequences
1236 self.tk.call(args)
Guido van Rossumc2966511998-04-10 19:16:10 +00001237
Fredrik Lundh06d28152000-08-09 18:03:12 +00001238 def event_delete(self, virtual, *sequences):
1239 """Unbind a virtual event VIRTUAL from SEQUENCE."""
1240 args = ('event', 'delete', virtual) + sequences
1241 self.tk.call(args)
Guido van Rossumc2966511998-04-10 19:16:10 +00001242
Fredrik Lundh06d28152000-08-09 18:03:12 +00001243 def event_generate(self, sequence, **kw):
1244 """Generate an event SEQUENCE. Additional
1245 keyword arguments specify parameter of the event
1246 (e.g. x, y, rootx, rooty)."""
1247 args = ('event', 'generate', self._w, sequence)
1248 for k, v in kw.items():
1249 args = args + ('-%s' % k, str(v))
1250 self.tk.call(args)
1251
1252 def event_info(self, virtual=None):
1253 """Return a list of all virtual events or the information
1254 about the SEQUENCE bound to the virtual event VIRTUAL."""
1255 return self.tk.splitlist(
1256 self.tk.call('event', 'info', virtual))
1257
1258 # Image related commands
1259
1260 def image_names(self):
1261 """Return a list of all existing image names."""
1262 return self.tk.call('image', 'names')
1263
1264 def image_types(self):
1265 """Return a list of all available image types (e.g. phote bitmap)."""
1266 return self.tk.call('image', 'types')
Guido van Rossumc2966511998-04-10 19:16:10 +00001267
Guido van Rossum80f8be81997-12-02 19:51:39 +00001268
Guido van Rossuma5773dd1995-09-07 19:22:00 +00001269class CallWrapper:
Fredrik Lundh06d28152000-08-09 18:03:12 +00001270 """Internal class. Stores function to call when some user
1271 defined Tcl function is called e.g. after an event occurred."""
1272 def __init__(self, func, subst, widget):
1273 """Store FUNC, SUBST and WIDGET as members."""
1274 self.func = func
1275 self.subst = subst
1276 self.widget = widget
1277 def __call__(self, *args):
1278 """Apply first function SUBST to arguments, than FUNC."""
1279 try:
1280 if self.subst:
1281 args = apply(self.subst, args)
1282 return apply(self.func, args)
1283 except SystemExit, msg:
1284 raise SystemExit, msg
1285 except:
1286 self.widget._report_exception()
Guido van Rossum18468821994-06-20 07:49:28 +00001287
Guido van Rossume365a591998-05-01 19:48:20 +00001288
Guido van Rossum18468821994-06-20 07:49:28 +00001289class Wm:
Fredrik Lundh06d28152000-08-09 18:03:12 +00001290 """Provides functions for the communication with the window manager."""
1291 def wm_aspect(self,
1292 minNumer=None, minDenom=None,
1293 maxNumer=None, maxDenom=None):
1294 """Instruct the window manager to set the aspect ratio (width/height)
1295 of this widget to be between MINNUMER/MINDENOM and MAXNUMER/MAXDENOM. Return a tuple
1296 of the actual values if no argument is given."""
1297 return self._getints(
1298 self.tk.call('wm', 'aspect', self._w,
1299 minNumer, minDenom,
1300 maxNumer, maxDenom))
1301 aspect = wm_aspect
1302 def wm_client(self, name=None):
1303 """Store NAME in WM_CLIENT_MACHINE property of this widget. Return
1304 current value."""
1305 return self.tk.call('wm', 'client', self._w, name)
1306 client = wm_client
1307 def wm_colormapwindows(self, *wlist):
1308 """Store list of window names (WLIST) into WM_COLORMAPWINDOWS property
1309 of this widget. This list contains windows whose colormaps differ from their
1310 parents. Return current list of widgets if WLIST is empty."""
1311 if len(wlist) > 1:
1312 wlist = (wlist,) # Tk needs a list of windows here
1313 args = ('wm', 'colormapwindows', self._w) + wlist
1314 return map(self._nametowidget, self.tk.call(args))
1315 colormapwindows = wm_colormapwindows
1316 def wm_command(self, value=None):
1317 """Store VALUE in WM_COMMAND property. It is the command
1318 which shall be used to invoke the application. Return current
1319 command if VALUE is None."""
1320 return self.tk.call('wm', 'command', self._w, value)
1321 command = wm_command
1322 def wm_deiconify(self):
1323 """Deiconify this widget. If it was never mapped it will not be mapped.
1324 On Windows it will raise this widget and give it the focus."""
1325 return self.tk.call('wm', 'deiconify', self._w)
1326 deiconify = wm_deiconify
1327 def wm_focusmodel(self, model=None):
1328 """Set focus model to MODEL. "active" means that this widget will claim
1329 the focus itself, "passive" means that the window manager shall give
1330 the focus. Return current focus model if MODEL is None."""
1331 return self.tk.call('wm', 'focusmodel', self._w, model)
1332 focusmodel = wm_focusmodel
1333 def wm_frame(self):
1334 """Return identifier for decorative frame of this widget if present."""
1335 return self.tk.call('wm', 'frame', self._w)
1336 frame = wm_frame
1337 def wm_geometry(self, newGeometry=None):
1338 """Set geometry to NEWGEOMETRY of the form =widthxheight+x+y. Return
1339 current value if None is given."""
1340 return self.tk.call('wm', 'geometry', self._w, newGeometry)
1341 geometry = wm_geometry
1342 def wm_grid(self,
1343 baseWidth=None, baseHeight=None,
1344 widthInc=None, heightInc=None):
1345 """Instruct the window manager that this widget shall only be
1346 resized on grid boundaries. WIDTHINC and HEIGHTINC are the width and
1347 height of a grid unit in pixels. BASEWIDTH and BASEHEIGHT are the
1348 number of grid units requested in Tk_GeometryRequest."""
1349 return self._getints(self.tk.call(
1350 'wm', 'grid', self._w,
1351 baseWidth, baseHeight, widthInc, heightInc))
1352 grid = wm_grid
1353 def wm_group(self, pathName=None):
1354 """Set the group leader widgets for related widgets to PATHNAME. Return
1355 the group leader of this widget if None is given."""
1356 return self.tk.call('wm', 'group', self._w, pathName)
1357 group = wm_group
1358 def wm_iconbitmap(self, bitmap=None):
1359 """Set bitmap for the iconified widget to BITMAP. Return
1360 the bitmap if None is given."""
1361 return self.tk.call('wm', 'iconbitmap', self._w, bitmap)
1362 iconbitmap = wm_iconbitmap
1363 def wm_iconify(self):
1364 """Display widget as icon."""
1365 return self.tk.call('wm', 'iconify', self._w)
1366 iconify = wm_iconify
1367 def wm_iconmask(self, bitmap=None):
1368 """Set mask for the icon bitmap of this widget. Return the
1369 mask if None is given."""
1370 return self.tk.call('wm', 'iconmask', self._w, bitmap)
1371 iconmask = wm_iconmask
1372 def wm_iconname(self, newName=None):
1373 """Set the name of the icon for this widget. Return the name if
1374 None is given."""
1375 return self.tk.call('wm', 'iconname', self._w, newName)
1376 iconname = wm_iconname
1377 def wm_iconposition(self, x=None, y=None):
1378 """Set the position of the icon of this widget to X and Y. Return
1379 a tuple of the current values of X and X if None is given."""
1380 return self._getints(self.tk.call(
1381 'wm', 'iconposition', self._w, x, y))
1382 iconposition = wm_iconposition
1383 def wm_iconwindow(self, pathName=None):
1384 """Set widget PATHNAME to be displayed instead of icon. Return the current
1385 value if None is given."""
1386 return self.tk.call('wm', 'iconwindow', self._w, pathName)
1387 iconwindow = wm_iconwindow
1388 def wm_maxsize(self, width=None, height=None):
1389 """Set max WIDTH and HEIGHT for this widget. If the window is gridded
1390 the values are given in grid units. Return the current values if None
1391 is given."""
1392 return self._getints(self.tk.call(
1393 'wm', 'maxsize', self._w, width, height))
1394 maxsize = wm_maxsize
1395 def wm_minsize(self, width=None, height=None):
1396 """Set min WIDTH and HEIGHT for this widget. If the window is gridded
1397 the values are given in grid units. Return the current values if None
1398 is given."""
1399 return self._getints(self.tk.call(
1400 'wm', 'minsize', self._w, width, height))
1401 minsize = wm_minsize
1402 def wm_overrideredirect(self, boolean=None):
1403 """Instruct the window manager to ignore this widget
1404 if BOOLEAN is given with 1. Return the current value if None
1405 is given."""
1406 return self._getboolean(self.tk.call(
1407 'wm', 'overrideredirect', self._w, boolean))
1408 overrideredirect = wm_overrideredirect
1409 def wm_positionfrom(self, who=None):
1410 """Instruct the window manager that the position of this widget shall
1411 be defined by the user if WHO is "user", and by its own policy if WHO is
1412 "program"."""
1413 return self.tk.call('wm', 'positionfrom', self._w, who)
1414 positionfrom = wm_positionfrom
1415 def wm_protocol(self, name=None, func=None):
1416 """Bind function FUNC to command NAME for this widget.
1417 Return the function bound to NAME if None is given. NAME could be
1418 e.g. "WM_SAVE_YOURSELF" or "WM_DELETE_WINDOW"."""
1419 if callable(func):
1420 command = self._register(func)
1421 else:
1422 command = func
1423 return self.tk.call(
1424 'wm', 'protocol', self._w, name, command)
1425 protocol = wm_protocol
1426 def wm_resizable(self, width=None, height=None):
1427 """Instruct the window manager whether this width can be resized
1428 in WIDTH or HEIGHT. Both values are boolean values."""
1429 return self.tk.call('wm', 'resizable', self._w, width, height)
1430 resizable = wm_resizable
1431 def wm_sizefrom(self, who=None):
1432 """Instruct the window manager that the size of this widget shall
1433 be defined by the user if WHO is "user", and by its own policy if WHO is
1434 "program"."""
1435 return self.tk.call('wm', 'sizefrom', self._w, who)
1436 sizefrom = wm_sizefrom
1437 def wm_state(self):
1438 """Return the state of this widget as one of normal,
1439 icon, iconic (see wm_iconwindow) and withdrawn."""
1440 return self.tk.call('wm', 'state', self._w)
1441 state = wm_state
1442 def wm_title(self, string=None):
1443 """Set the title of this widget."""
1444 return self.tk.call('wm', 'title', self._w, string)
1445 title = wm_title
1446 def wm_transient(self, master=None):
1447 """Instruct the window manager that this widget is transient
1448 with regard to widget MASTER."""
1449 return self.tk.call('wm', 'transient', self._w, master)
1450 transient = wm_transient
1451 def wm_withdraw(self):
1452 """Withdraw this widget from the screen such that it is unmapped
1453 and forgotten by the window manager. Re-draw it with wm_deiconify."""
1454 return self.tk.call('wm', 'withdraw', self._w)
1455 withdraw = wm_withdraw
Guido van Rossume365a591998-05-01 19:48:20 +00001456
Guido van Rossum18468821994-06-20 07:49:28 +00001457
1458class Tk(Misc, Wm):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001459 """Toplevel widget of Tk which represents mostly the main window
1460 of an appliation. It has an associated Tcl interpreter."""
1461 _w = '.'
1462 def __init__(self, screenName=None, baseName=None, className='Tk'):
1463 """Return a new Toplevel widget on screen SCREENNAME. A new Tcl interpreter will
1464 be created. BASENAME will be used for the identification of the profile file (see
1465 readprofile).
1466 It is constructed from sys.argv[0] without extensions if None is given. CLASSNAME
1467 is the name of the widget class."""
1468 global _default_root
1469 self.master = None
1470 self.children = {}
1471 if baseName is None:
1472 import sys, os
1473 baseName = os.path.basename(sys.argv[0])
1474 baseName, ext = os.path.splitext(baseName)
1475 if ext not in ('.py', '.pyc', '.pyo'):
1476 baseName = baseName + ext
1477 self.tk = _tkinter.create(screenName, baseName, className)
1478 if _MacOS:
1479 # Disable event scanning except for Command-Period
1480 _MacOS.SchedParams(1, 0)
1481 # Work around nasty MacTk bug
1482 # XXX Is this one still needed?
1483 self.update()
1484 # Version sanity checks
1485 tk_version = self.tk.getvar('tk_version')
1486 if tk_version != _tkinter.TK_VERSION:
1487 raise RuntimeError, \
1488 "tk.h version (%s) doesn't match libtk.a version (%s)" \
1489 % (_tkinter.TK_VERSION, tk_version)
1490 tcl_version = self.tk.getvar('tcl_version')
1491 if tcl_version != _tkinter.TCL_VERSION:
1492 raise RuntimeError, \
1493 "tcl.h version (%s) doesn't match libtcl.a version (%s)" \
1494 % (_tkinter.TCL_VERSION, tcl_version)
1495 if TkVersion < 4.0:
1496 raise RuntimeError, \
1497 "Tk 4.0 or higher is required; found Tk %s" \
1498 % str(TkVersion)
1499 self.tk.createcommand('tkerror', _tkerror)
1500 self.tk.createcommand('exit', _exit)
1501 self.readprofile(baseName, className)
1502 if _support_default_root and not _default_root:
1503 _default_root = self
1504 self.protocol("WM_DELETE_WINDOW", self.destroy)
1505 def destroy(self):
1506 """Destroy this and all descendants widgets. This will
1507 end the application of this Tcl interpreter."""
1508 for c in self.children.values(): c.destroy()
1509 self.tk.call('destroy', self._w)
1510 Misc.destroy(self)
1511 global _default_root
1512 if _support_default_root and _default_root is self:
1513 _default_root = None
1514 def readprofile(self, baseName, className):
1515 """Internal function. It reads BASENAME.tcl and CLASSNAME.tcl into
1516 the Tcl Interpreter and calls execfile on BASENAME.py and CLASSNAME.py if
1517 such a file exists in the home directory."""
1518 import os
1519 if os.environ.has_key('HOME'): home = os.environ['HOME']
1520 else: home = os.curdir
1521 class_tcl = os.path.join(home, '.%s.tcl' % className)
1522 class_py = os.path.join(home, '.%s.py' % className)
1523 base_tcl = os.path.join(home, '.%s.tcl' % baseName)
1524 base_py = os.path.join(home, '.%s.py' % baseName)
1525 dir = {'self': self}
1526 exec 'from Tkinter import *' in dir
1527 if os.path.isfile(class_tcl):
1528 print 'source', `class_tcl`
1529 self.tk.call('source', class_tcl)
1530 if os.path.isfile(class_py):
1531 print 'execfile', `class_py`
1532 execfile(class_py, dir)
1533 if os.path.isfile(base_tcl):
1534 print 'source', `base_tcl`
1535 self.tk.call('source', base_tcl)
1536 if os.path.isfile(base_py):
1537 print 'execfile', `base_py`
1538 execfile(base_py, dir)
1539 def report_callback_exception(self, exc, val, tb):
1540 """Internal function. It reports exception on sys.stderr."""
1541 import traceback, sys
1542 sys.stderr.write("Exception in Tkinter callback\n")
1543 sys.last_type = exc
1544 sys.last_value = val
1545 sys.last_traceback = tb
1546 traceback.print_exception(exc, val, tb)
Guido van Rossum18468821994-06-20 07:49:28 +00001547
Guido van Rossum368e06b1997-11-07 20:38:49 +00001548# Ideally, the classes Pack, Place and Grid disappear, the
1549# pack/place/grid methods are defined on the Widget class, and
1550# everybody uses w.pack_whatever(...) instead of Pack.whatever(w,
1551# ...), with pack(), place() and grid() being short for
1552# pack_configure(), place_configure() and grid_columnconfigure(), and
1553# forget() being short for pack_forget(). As a practical matter, I'm
1554# afraid that there is too much code out there that may be using the
1555# Pack, Place or Grid class, so I leave them intact -- but only as
1556# backwards compatibility features. Also note that those methods that
1557# take a master as argument (e.g. pack_propagate) have been moved to
1558# the Misc class (which now incorporates all methods common between
1559# toplevel and interior widgets). Again, for compatibility, these are
1560# copied into the Pack, Place or Grid class.
1561
Guido van Rossum18468821994-06-20 07:49:28 +00001562class Pack:
Fredrik Lundh06d28152000-08-09 18:03:12 +00001563 """Geometry manager Pack.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001564
Fredrik Lundh06d28152000-08-09 18:03:12 +00001565 Base class to use the methods pack_* in every widget."""
1566 def pack_configure(self, cnf={}, **kw):
1567 """Pack a widget in the parent widget. Use as options:
1568 after=widget - pack it after you have packed widget
1569 anchor=NSEW (or subset) - position widget according to
1570 given direction
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001571 before=widget - pack it before you will pack widget
Fredrik Lundh06d28152000-08-09 18:03:12 +00001572 expand=1 or 0 - expand widget if parent size grows
1573 fill=NONE or X or Y or BOTH - fill widget if widget grows
1574 in=master - use master to contain this widget
1575 ipadx=amount - add internal padding in x direction
1576 ipady=amount - add internal padding in y direction
1577 padx=amount - add padding in x direction
1578 pady=amount - add padding in y direction
1579 side=TOP or BOTTOM or LEFT or RIGHT - where to add this widget.
1580 """
1581 self.tk.call(
1582 ('pack', 'configure', self._w)
1583 + self._options(cnf, kw))
1584 pack = configure = config = pack_configure
1585 def pack_forget(self):
1586 """Unmap this widget and do not use it for the packing order."""
1587 self.tk.call('pack', 'forget', self._w)
1588 forget = pack_forget
1589 def pack_info(self):
1590 """Return information about the packing options
1591 for this widget."""
1592 words = self.tk.splitlist(
1593 self.tk.call('pack', 'info', self._w))
1594 dict = {}
1595 for i in range(0, len(words), 2):
1596 key = words[i][1:]
1597 value = words[i+1]
1598 if value[:1] == '.':
1599 value = self._nametowidget(value)
1600 dict[key] = value
1601 return dict
1602 info = pack_info
1603 propagate = pack_propagate = Misc.pack_propagate
1604 slaves = pack_slaves = Misc.pack_slaves
Guido van Rossum18468821994-06-20 07:49:28 +00001605
1606class Place:
Fredrik Lundh06d28152000-08-09 18:03:12 +00001607 """Geometry manager Place.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001608
Fredrik Lundh06d28152000-08-09 18:03:12 +00001609 Base class to use the methods place_* in every widget."""
1610 def place_configure(self, cnf={}, **kw):
1611 """Place a widget in the parent widget. Use as options:
1612 in=master - master relative to which the widget is placed.
1613 x=amount - locate anchor of this widget at position x of master
1614 y=amount - locate anchor of this widget at position y of master
1615 relx=amount - locate anchor of this widget between 0.0 and 1.0
1616 relative to width of master (1.0 is right edge)
1617 rely=amount - locate anchor of this widget between 0.0 and 1.0
1618 relative to height of master (1.0 is bottom edge)
1619 anchor=NSEW (or subset) - position anchor according to given direction
1620 width=amount - width of this widget in pixel
1621 height=amount - height of this widget in pixel
1622 relwidth=amount - width of this widget between 0.0 and 1.0
1623 relative to width of master (1.0 is the same width
1624 as the master)
1625 relheight=amount - height of this widget between 0.0 and 1.0
1626 relative to height of master (1.0 is the same
1627 height as the master)
1628 bordermode="inside" or "outside" - whether to take border width of master widget
1629 into account
1630 """
1631 for k in ['in_']:
1632 if kw.has_key(k):
1633 kw[k[:-1]] = kw[k]
1634 del kw[k]
1635 self.tk.call(
1636 ('place', 'configure', self._w)
1637 + self._options(cnf, kw))
1638 place = configure = config = place_configure
1639 def place_forget(self):
1640 """Unmap this widget."""
1641 self.tk.call('place', 'forget', self._w)
1642 forget = place_forget
1643 def place_info(self):
1644 """Return information about the placing options
1645 for this widget."""
1646 words = self.tk.splitlist(
1647 self.tk.call('place', 'info', self._w))
1648 dict = {}
1649 for i in range(0, len(words), 2):
1650 key = words[i][1:]
1651 value = words[i+1]
1652 if value[:1] == '.':
1653 value = self._nametowidget(value)
1654 dict[key] = value
1655 return dict
1656 info = place_info
1657 slaves = place_slaves = Misc.place_slaves
Guido van Rossum18468821994-06-20 07:49:28 +00001658
Guido van Rossum37dcab11996-05-16 16:00:19 +00001659class Grid:
Fredrik Lundh06d28152000-08-09 18:03:12 +00001660 """Geometry manager Grid.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001661
Fredrik Lundh06d28152000-08-09 18:03:12 +00001662 Base class to use the methods grid_* in every widget."""
1663 # Thanks to Masazumi Yoshikawa (yosikawa@isi.edu)
1664 def grid_configure(self, cnf={}, **kw):
1665 """Position a widget in the parent widget in a grid. Use as options:
1666 column=number - use cell identified with given column (starting with 0)
1667 columnspan=number - this widget will span several columns
1668 in=master - use master to contain this widget
1669 ipadx=amount - add internal padding in x direction
1670 ipady=amount - add internal padding in y direction
1671 padx=amount - add padding in x direction
1672 pady=amount - add padding in y direction
1673 row=number - use cell identified with given row (starting with 0)
1674 rowspan=number - this widget will span several rows
1675 sticky=NSEW - if cell is larger on which sides will this
1676 widget stick to the cell boundary
1677 """
1678 self.tk.call(
1679 ('grid', 'configure', self._w)
1680 + self._options(cnf, kw))
1681 grid = configure = config = grid_configure
1682 bbox = grid_bbox = Misc.grid_bbox
1683 columnconfigure = grid_columnconfigure = Misc.grid_columnconfigure
1684 def grid_forget(self):
1685 """Unmap this widget."""
1686 self.tk.call('grid', 'forget', self._w)
1687 forget = grid_forget
1688 def grid_remove(self):
1689 """Unmap this widget but remember the grid options."""
1690 self.tk.call('grid', 'remove', self._w)
1691 def grid_info(self):
1692 """Return information about the options
1693 for positioning this widget in a grid."""
1694 words = self.tk.splitlist(
1695 self.tk.call('grid', 'info', self._w))
1696 dict = {}
1697 for i in range(0, len(words), 2):
1698 key = words[i][1:]
1699 value = words[i+1]
1700 if value[:1] == '.':
1701 value = self._nametowidget(value)
1702 dict[key] = value
1703 return dict
1704 info = grid_info
1705 def grid_location(self, x, y):
1706 """Return a tuple of column and row which identify the cell
1707 at which the pixel at position X and Y inside the master
1708 widget is located."""
1709 return self._getints(
1710 self.tk.call(
1711 'grid', 'location', self._w, x, y)) or None
1712 location = grid_location
1713 propagate = grid_propagate = Misc.grid_propagate
1714 rowconfigure = grid_rowconfigure = Misc.grid_rowconfigure
1715 size = grid_size = Misc.grid_size
1716 slaves = grid_slaves = Misc.grid_slaves
Guido van Rossum37dcab11996-05-16 16:00:19 +00001717
Guido van Rossum368e06b1997-11-07 20:38:49 +00001718class BaseWidget(Misc):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001719 """Internal class."""
1720 def _setup(self, master, cnf):
1721 """Internal function. Sets up information about children."""
1722 if _support_default_root:
1723 global _default_root
1724 if not master:
1725 if not _default_root:
1726 _default_root = Tk()
1727 master = _default_root
1728 self.master = master
1729 self.tk = master.tk
1730 name = None
1731 if cnf.has_key('name'):
1732 name = cnf['name']
1733 del cnf['name']
1734 if not name:
1735 name = `id(self)`
1736 self._name = name
1737 if master._w=='.':
1738 self._w = '.' + name
1739 else:
1740 self._w = master._w + '.' + name
1741 self.children = {}
1742 if self.master.children.has_key(self._name):
1743 self.master.children[self._name].destroy()
1744 self.master.children[self._name] = self
1745 def __init__(self, master, widgetName, cnf={}, kw={}, extra=()):
1746 """Construct a widget with the parent widget MASTER, a name WIDGETNAME
1747 and appropriate options."""
1748 if kw:
1749 cnf = _cnfmerge((cnf, kw))
1750 self.widgetName = widgetName
1751 BaseWidget._setup(self, master, cnf)
1752 classes = []
1753 for k in cnf.keys():
1754 if type(k) is ClassType:
1755 classes.append((k, cnf[k]))
1756 del cnf[k]
1757 self.tk.call(
1758 (widgetName, self._w) + extra + self._options(cnf))
1759 for k, v in classes:
1760 k.configure(self, v)
1761 def destroy(self):
1762 """Destroy this and all descendants widgets."""
1763 for c in self.children.values(): c.destroy()
1764 if self.master.children.has_key(self._name):
1765 del self.master.children[self._name]
1766 self.tk.call('destroy', self._w)
1767 Misc.destroy(self)
1768 def _do(self, name, args=()):
1769 # XXX Obsolete -- better use self.tk.call directly!
1770 return self.tk.call((self._w, name) + args)
Guido van Rossum18468821994-06-20 07:49:28 +00001771
Guido van Rossum368e06b1997-11-07 20:38:49 +00001772class Widget(BaseWidget, Pack, Place, Grid):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001773 """Internal class.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001774
Fredrik Lundh06d28152000-08-09 18:03:12 +00001775 Base class for a widget which can be positioned with the geometry managers
1776 Pack, Place or Grid."""
1777 pass
Guido van Rossum368e06b1997-11-07 20:38:49 +00001778
1779class Toplevel(BaseWidget, Wm):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001780 """Toplevel widget, e.g. for dialogs."""
1781 def __init__(self, master=None, cnf={}, **kw):
1782 """Construct a toplevel widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001783
Fredrik Lundh06d28152000-08-09 18:03:12 +00001784 Valid resource names: background, bd, bg, borderwidth, class,
1785 colormap, container, cursor, height, highlightbackground,
1786 highlightcolor, highlightthickness, menu, relief, screen, takefocus,
1787 use, visual, width."""
1788 if kw:
1789 cnf = _cnfmerge((cnf, kw))
1790 extra = ()
1791 for wmkey in ['screen', 'class_', 'class', 'visual',
1792 'colormap']:
1793 if cnf.has_key(wmkey):
1794 val = cnf[wmkey]
1795 # TBD: a hack needed because some keys
1796 # are not valid as keyword arguments
1797 if wmkey[-1] == '_': opt = '-'+wmkey[:-1]
1798 else: opt = '-'+wmkey
1799 extra = extra + (opt, val)
1800 del cnf[wmkey]
1801 BaseWidget.__init__(self, master, 'toplevel', cnf, {}, extra)
1802 root = self._root()
1803 self.iconname(root.iconname())
1804 self.title(root.title())
1805 self.protocol("WM_DELETE_WINDOW", self.destroy)
Guido van Rossum18468821994-06-20 07:49:28 +00001806
1807class Button(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001808 """Button widget."""
1809 def __init__(self, master=None, cnf={}, **kw):
1810 """Construct a button widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001811
Fredrik Lundh06d28152000-08-09 18:03:12 +00001812 Valid resource names: activebackground, activeforeground, anchor,
1813 background, bd, bg, bitmap, borderwidth, command, cursor, default,
1814 disabledforeground, fg, font, foreground, height,
1815 highlightbackground, highlightcolor, highlightthickness, image,
1816 justify, padx, pady, relief, state, takefocus, text, textvariable,
1817 underline, width, wraplength."""
1818 Widget.__init__(self, master, 'button', cnf, kw)
1819 def tkButtonEnter(self, *dummy):
1820 self.tk.call('tkButtonEnter', self._w)
1821 def tkButtonLeave(self, *dummy):
1822 self.tk.call('tkButtonLeave', self._w)
1823 def tkButtonDown(self, *dummy):
1824 self.tk.call('tkButtonDown', self._w)
1825 def tkButtonUp(self, *dummy):
1826 self.tk.call('tkButtonUp', self._w)
1827 def tkButtonInvoke(self, *dummy):
1828 self.tk.call('tkButtonInvoke', self._w)
1829 def flash(self):
1830 self.tk.call(self._w, 'flash')
1831 def invoke(self):
1832 return self.tk.call(self._w, 'invoke')
Guido van Rossum18468821994-06-20 07:49:28 +00001833
1834# Indices:
Guido van Rossum35f67fb1995-08-04 03:50:29 +00001835# XXX I don't like these -- take them away
Guido van Rossum18468821994-06-20 07:49:28 +00001836def AtEnd():
Fredrik Lundh06d28152000-08-09 18:03:12 +00001837 return 'end'
Guido van Rossum1e9e4001994-06-20 09:09:51 +00001838def AtInsert(*args):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001839 s = 'insert'
1840 for a in args:
1841 if a: s = s + (' ' + a)
1842 return s
Guido van Rossum18468821994-06-20 07:49:28 +00001843def AtSelFirst():
Fredrik Lundh06d28152000-08-09 18:03:12 +00001844 return 'sel.first'
Guido van Rossum18468821994-06-20 07:49:28 +00001845def AtSelLast():
Fredrik Lundh06d28152000-08-09 18:03:12 +00001846 return 'sel.last'
Guido van Rossum18468821994-06-20 07:49:28 +00001847def At(x, y=None):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001848 if y is None:
1849 return '@' + `x`
1850 else:
1851 return '@' + `x` + ',' + `y`
Guido van Rossum18468821994-06-20 07:49:28 +00001852
1853class Canvas(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00001854 """Canvas widget to display graphical elements like lines or text."""
1855 def __init__(self, master=None, cnf={}, **kw):
1856 """Construct a canvas widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001857
Fredrik Lundh06d28152000-08-09 18:03:12 +00001858 Valid resource names: background, bd, bg, borderwidth, closeenough,
1859 confine, cursor, height, highlightbackground, highlightcolor,
1860 highlightthickness, insertbackground, insertborderwidth,
1861 insertofftime, insertontime, insertwidth, offset, relief,
1862 scrollregion, selectbackground, selectborderwidth, selectforeground,
1863 state, takefocus, width, xscrollcommand, xscrollincrement,
1864 yscrollcommand, yscrollincrement."""
1865 Widget.__init__(self, master, 'canvas', cnf, kw)
1866 def addtag(self, *args):
1867 """Internal function."""
1868 self.tk.call((self._w, 'addtag') + args)
1869 def addtag_above(self, newtag, tagOrId):
1870 """Add tag NEWTAG to all items above TAGORID."""
1871 self.addtag(newtag, 'above', tagOrId)
1872 def addtag_all(self, newtag):
1873 """Add tag NEWTAG to all items."""
1874 self.addtag(newtag, 'all')
1875 def addtag_below(self, newtag, tagOrId):
1876 """Add tag NEWTAG to all items below TAGORID."""
1877 self.addtag(newtag, 'below', tagOrId)
1878 def addtag_closest(self, newtag, x, y, halo=None, start=None):
1879 """Add tag NEWTAG to item which is closest to pixel at X, Y.
1880 If several match take the top-most.
1881 All items closer than HALO are considered overlapping (all are
1882 closests). If START is specified the next below this tag is taken."""
1883 self.addtag(newtag, 'closest', x, y, halo, start)
1884 def addtag_enclosed(self, newtag, x1, y1, x2, y2):
1885 """Add tag NEWTAG to all items in the rectangle defined
1886 by X1,Y1,X2,Y2."""
1887 self.addtag(newtag, 'enclosed', x1, y1, x2, y2)
1888 def addtag_overlapping(self, newtag, x1, y1, x2, y2):
1889 """Add tag NEWTAG to all items which overlap the rectangle
1890 defined by X1,Y1,X2,Y2."""
1891 self.addtag(newtag, 'overlapping', x1, y1, x2, y2)
1892 def addtag_withtag(self, newtag, tagOrId):
1893 """Add tag NEWTAG to all items with TAGORID."""
1894 self.addtag(newtag, 'withtag', tagOrId)
1895 def bbox(self, *args):
1896 """Return a tuple of X1,Y1,X2,Y2 coordinates for a rectangle
1897 which encloses all items with tags specified as arguments."""
1898 return self._getints(
1899 self.tk.call((self._w, 'bbox') + args)) or None
1900 def tag_unbind(self, tagOrId, sequence, funcid=None):
1901 """Unbind for all items with TAGORID for event SEQUENCE the
1902 function identified with FUNCID."""
1903 self.tk.call(self._w, 'bind', tagOrId, sequence, '')
1904 if funcid:
1905 self.deletecommand(funcid)
1906 def tag_bind(self, tagOrId, sequence=None, func=None, add=None):
1907 """Bind to all items with TAGORID at event SEQUENCE a call to function FUNC.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00001908
Fredrik Lundh06d28152000-08-09 18:03:12 +00001909 An additional boolean parameter ADD specifies whether FUNC will be
1910 called additionally to the other bound function or whether it will
1911 replace the previous function. See bind for the return value."""
1912 return self._bind((self._w, 'bind', tagOrId),
1913 sequence, func, add)
1914 def canvasx(self, screenx, gridspacing=None):
1915 """Return the canvas x coordinate of pixel position SCREENX rounded
1916 to nearest multiple of GRIDSPACING units."""
1917 return getdouble(self.tk.call(
1918 self._w, 'canvasx', screenx, gridspacing))
1919 def canvasy(self, screeny, gridspacing=None):
1920 """Return the canvas y coordinate of pixel position SCREENY rounded
1921 to nearest multiple of GRIDSPACING units."""
1922 return getdouble(self.tk.call(
1923 self._w, 'canvasy', screeny, gridspacing))
1924 def coords(self, *args):
1925 """Return a list of coordinates for the item given in ARGS."""
1926 # XXX Should use _flatten on args
1927 return map(getdouble,
Guido van Rossum0bd54331998-05-19 21:18:13 +00001928 self.tk.splitlist(
Fredrik Lundh06d28152000-08-09 18:03:12 +00001929 self.tk.call((self._w, 'coords') + args)))
1930 def _create(self, itemType, args, kw): # Args: (val, val, ..., cnf={})
1931 """Internal function."""
1932 args = _flatten(args)
1933 cnf = args[-1]
1934 if type(cnf) in (DictionaryType, TupleType):
1935 args = args[:-1]
1936 else:
1937 cnf = {}
1938 return getint(apply(
1939 self.tk.call,
1940 (self._w, 'create', itemType)
1941 + args + self._options(cnf, kw)))
1942 def create_arc(self, *args, **kw):
1943 """Create arc shaped region with coordinates x1,y1,x2,y2."""
1944 return self._create('arc', args, kw)
1945 def create_bitmap(self, *args, **kw):
1946 """Create bitmap with coordinates x1,y1."""
1947 return self._create('bitmap', args, kw)
1948 def create_image(self, *args, **kw):
1949 """Create image item with coordinates x1,y1."""
1950 return self._create('image', args, kw)
1951 def create_line(self, *args, **kw):
1952 """Create line with coordinates x1,y1,...,xn,yn."""
1953 return self._create('line', args, kw)
1954 def create_oval(self, *args, **kw):
1955 """Create oval with coordinates x1,y1,x2,y2."""
1956 return self._create('oval', args, kw)
1957 def create_polygon(self, *args, **kw):
1958 """Create polygon with coordinates x1,y1,...,xn,yn."""
1959 return self._create('polygon', args, kw)
1960 def create_rectangle(self, *args, **kw):
1961 """Create rectangle with coordinates x1,y1,x2,y2."""
1962 return self._create('rectangle', args, kw)
1963 def create_text(self, *args, **kw):
1964 """Create text with coordinates x1,y1."""
1965 return self._create('text', args, kw)
1966 def create_window(self, *args, **kw):
1967 """Create window with coordinates x1,y1,x2,y2."""
1968 return self._create('window', args, kw)
1969 def dchars(self, *args):
1970 """Delete characters of text items identified by tag or id in ARGS (possibly
1971 several times) from FIRST to LAST character (including)."""
1972 self.tk.call((self._w, 'dchars') + args)
1973 def delete(self, *args):
1974 """Delete items identified by all tag or ids contained in ARGS."""
1975 self.tk.call((self._w, 'delete') + args)
1976 def dtag(self, *args):
1977 """Delete tag or id given as last arguments in ARGS from items
1978 identified by first argument in ARGS."""
1979 self.tk.call((self._w, 'dtag') + args)
1980 def find(self, *args):
1981 """Internal function."""
1982 return self._getints(
1983 self.tk.call((self._w, 'find') + args)) or ()
1984 def find_above(self, tagOrId):
1985 """Return items above TAGORID."""
1986 return self.find('above', tagOrId)
1987 def find_all(self):
1988 """Return all items."""
1989 return self.find('all')
1990 def find_below(self, tagOrId):
1991 """Return all items below TAGORID."""
1992 return self.find('below', tagOrId)
1993 def find_closest(self, x, y, halo=None, start=None):
1994 """Return item which is closest to pixel at X, Y.
1995 If several match take the top-most.
1996 All items closer than HALO are considered overlapping (all are
1997 closests). If START is specified the next below this tag is taken."""
1998 return self.find('closest', x, y, halo, start)
1999 def find_enclosed(self, x1, y1, x2, y2):
2000 """Return all items in rectangle defined
2001 by X1,Y1,X2,Y2."""
2002 return self.find('enclosed', x1, y1, x2, y2)
2003 def find_overlapping(self, x1, y1, x2, y2):
2004 """Return all items which overlap the rectangle
2005 defined by X1,Y1,X2,Y2."""
2006 return self.find('overlapping', x1, y1, x2, y2)
2007 def find_withtag(self, tagOrId):
2008 """Return all items with TAGORID."""
2009 return self.find('withtag', tagOrId)
2010 def focus(self, *args):
2011 """Set focus to the first item specified in ARGS."""
2012 return self.tk.call((self._w, 'focus') + args)
2013 def gettags(self, *args):
2014 """Return tags associated with the first item specified in ARGS."""
2015 return self.tk.splitlist(
2016 self.tk.call((self._w, 'gettags') + args))
2017 def icursor(self, *args):
2018 """Set cursor at position POS in the item identified by TAGORID.
2019 In ARGS TAGORID must be first."""
2020 self.tk.call((self._w, 'icursor') + args)
2021 def index(self, *args):
2022 """Return position of cursor as integer in item specified in ARGS."""
2023 return getint(self.tk.call((self._w, 'index') + args))
2024 def insert(self, *args):
2025 """Insert TEXT in item TAGORID at position POS. ARGS must
2026 be TAGORID POS TEXT."""
2027 self.tk.call((self._w, 'insert') + args)
2028 def itemcget(self, tagOrId, option):
2029 """Return the resource value for an OPTION for item TAGORID."""
2030 return self.tk.call(
2031 (self._w, 'itemcget') + (tagOrId, '-'+option))
2032 def itemconfigure(self, tagOrId, cnf=None, **kw):
2033 """Configure resources of an item TAGORID.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002034
Fredrik Lundh06d28152000-08-09 18:03:12 +00002035 The values for resources are specified as keyword
2036 arguments. To get an overview about
2037 the allowed keyword arguments call the method without arguments.
2038 """
2039 if cnf is None and not kw:
2040 cnf = {}
2041 for x in self.tk.split(
2042 self.tk.call(self._w,
2043 'itemconfigure', tagOrId)):
2044 cnf[x[0][1:]] = (x[0][1:],) + x[1:]
2045 return cnf
2046 if type(cnf) == StringType and not kw:
2047 x = self.tk.split(self.tk.call(
2048 self._w, 'itemconfigure', tagOrId, '-'+cnf))
2049 return (x[0][1:],) + x[1:]
2050 self.tk.call((self._w, 'itemconfigure', tagOrId) +
2051 self._options(cnf, kw))
2052 itemconfig = itemconfigure
2053 # lower, tkraise/lift hide Misc.lower, Misc.tkraise/lift,
2054 # so the preferred name for them is tag_lower, tag_raise
2055 # (similar to tag_bind, and similar to the Text widget);
2056 # unfortunately can't delete the old ones yet (maybe in 1.6)
2057 def tag_lower(self, *args):
2058 """Lower an item TAGORID given in ARGS
2059 (optional below another item)."""
2060 self.tk.call((self._w, 'lower') + args)
2061 lower = tag_lower
2062 def move(self, *args):
2063 """Move an item TAGORID given in ARGS."""
2064 self.tk.call((self._w, 'move') + args)
2065 def postscript(self, cnf={}, **kw):
2066 """Print the contents of the canvas to a postscript
2067 file. Valid options: colormap, colormode, file, fontmap,
2068 height, pageanchor, pageheight, pagewidth, pagex, pagey,
2069 rotate, witdh, x, y."""
2070 return self.tk.call((self._w, 'postscript') +
2071 self._options(cnf, kw))
2072 def tag_raise(self, *args):
2073 """Raise an item TAGORID given in ARGS
2074 (optional above another item)."""
2075 self.tk.call((self._w, 'raise') + args)
2076 lift = tkraise = tag_raise
2077 def scale(self, *args):
2078 """Scale item TAGORID with XORIGIN, YORIGIN, XSCALE, YSCALE."""
2079 self.tk.call((self._w, 'scale') + args)
2080 def scan_mark(self, x, y):
2081 """Remember the current X, Y coordinates."""
2082 self.tk.call(self._w, 'scan', 'mark', x, y)
2083 def scan_dragto(self, x, y):
2084 """Adjust the view of the canvas to 10 times the
2085 difference between X and Y and the coordinates given in
2086 scan_mark."""
2087 self.tk.call(self._w, 'scan', 'dragto', x, y)
2088 def select_adjust(self, tagOrId, index):
2089 """Adjust the end of the selection near the cursor of an item TAGORID to index."""
2090 self.tk.call(self._w, 'select', 'adjust', tagOrId, index)
2091 def select_clear(self):
2092 """Clear the selection if it is in this widget."""
2093 self.tk.call(self._w, 'select', 'clear')
2094 def select_from(self, tagOrId, index):
2095 """Set the fixed end of a selection in item TAGORID to INDEX."""
2096 self.tk.call(self._w, 'select', 'from', tagOrId, index)
2097 def select_item(self):
2098 """Return the item which has the selection."""
2099 self.tk.call(self._w, 'select', 'item')
2100 def select_to(self, tagOrId, index):
2101 """Set the variable end of a selection in item TAGORID to INDEX."""
2102 self.tk.call(self._w, 'select', 'to', tagOrId, index)
2103 def type(self, tagOrId):
2104 """Return the type of the item TAGORID."""
2105 return self.tk.call(self._w, 'type', tagOrId) or None
2106 def xview(self, *args):
2107 """Query and change horizontal position of the view."""
2108 if not args:
2109 return self._getdoubles(self.tk.call(self._w, 'xview'))
2110 self.tk.call((self._w, 'xview') + args)
2111 def xview_moveto(self, fraction):
2112 """Adjusts the view in the window so that FRACTION of the
2113 total width of the canvas is off-screen to the left."""
2114 self.tk.call(self._w, 'xview', 'moveto', fraction)
2115 def xview_scroll(self, number, what):
2116 """Shift the x-view according to NUMBER which is measured in "units" or "pages" (WHAT)."""
2117 self.tk.call(self._w, 'xview', 'scroll', number, what)
2118 def yview(self, *args):
2119 """Query and change vertical position of the view."""
2120 if not args:
2121 return self._getdoubles(self.tk.call(self._w, 'yview'))
2122 self.tk.call((self._w, 'yview') + args)
2123 def yview_moveto(self, fraction):
2124 """Adjusts the view in the window so that FRACTION of the
2125 total height of the canvas is off-screen to the top."""
2126 self.tk.call(self._w, 'yview', 'moveto', fraction)
2127 def yview_scroll(self, number, what):
2128 """Shift the y-view according to NUMBER which is measured in "units" or "pages" (WHAT)."""
2129 self.tk.call(self._w, 'yview', 'scroll', number, what)
Guido van Rossum18468821994-06-20 07:49:28 +00002130
2131class Checkbutton(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002132 """Checkbutton widget which is either in on- or off-state."""
2133 def __init__(self, master=None, cnf={}, **kw):
2134 """Construct a checkbutton widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002135
Fredrik Lundh06d28152000-08-09 18:03:12 +00002136 Valid resource names: activebackground, activeforeground, anchor,
2137 background, bd, bg, bitmap, borderwidth, command, cursor,
2138 disabledforeground, fg, font, foreground, height,
2139 highlightbackground, highlightcolor, highlightthickness, image,
2140 indicatoron, justify, offvalue, onvalue, padx, pady, relief,
2141 selectcolor, selectimage, state, takefocus, text, textvariable,
2142 underline, variable, width, wraplength."""
2143 Widget.__init__(self, master, 'checkbutton', cnf, kw)
2144 def deselect(self):
2145 """Put the button in off-state."""
2146 self.tk.call(self._w, 'deselect')
2147 def flash(self):
2148 """Flash the button."""
2149 self.tk.call(self._w, 'flash')
2150 def invoke(self):
2151 """Toggle the button and invoke a command if given as resource."""
2152 return self.tk.call(self._w, 'invoke')
2153 def select(self):
2154 """Put the button in on-state."""
2155 self.tk.call(self._w, 'select')
2156 def toggle(self):
2157 """Toggle the button."""
2158 self.tk.call(self._w, 'toggle')
Guido van Rossum18468821994-06-20 07:49:28 +00002159
2160class Entry(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002161 """Entry widget which allows to display simple text."""
2162 def __init__(self, master=None, cnf={}, **kw):
2163 """Construct an entry widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002164
Fredrik Lundh06d28152000-08-09 18:03:12 +00002165 Valid resource names: background, bd, bg, borderwidth, cursor,
2166 exportselection, fg, font, foreground, highlightbackground,
2167 highlightcolor, highlightthickness, insertbackground,
2168 insertborderwidth, insertofftime, insertontime, insertwidth,
2169 invalidcommand, invcmd, justify, relief, selectbackground,
2170 selectborderwidth, selectforeground, show, state, takefocus,
2171 textvariable, validate, validatecommand, vcmd, width,
2172 xscrollcommand."""
2173 Widget.__init__(self, master, 'entry', cnf, kw)
2174 def delete(self, first, last=None):
2175 """Delete text from FIRST to LAST (not included)."""
2176 self.tk.call(self._w, 'delete', first, last)
2177 def get(self):
2178 """Return the text."""
2179 return self.tk.call(self._w, 'get')
2180 def icursor(self, index):
2181 """Insert cursor at INDEX."""
2182 self.tk.call(self._w, 'icursor', index)
2183 def index(self, index):
2184 """Return position of cursor."""
2185 return getint(self.tk.call(
2186 self._w, 'index', index))
2187 def insert(self, index, string):
2188 """Insert STRING at INDEX."""
2189 self.tk.call(self._w, 'insert', index, string)
2190 def scan_mark(self, x):
2191 """Remember the current X, Y coordinates."""
2192 self.tk.call(self._w, 'scan', 'mark', x)
2193 def scan_dragto(self, x):
2194 """Adjust the view of the canvas to 10 times the
2195 difference between X and Y and the coordinates given in
2196 scan_mark."""
2197 self.tk.call(self._w, 'scan', 'dragto', x)
2198 def selection_adjust(self, index):
2199 """Adjust the end of the selection near the cursor to INDEX."""
2200 self.tk.call(self._w, 'selection', 'adjust', index)
2201 select_adjust = selection_adjust
2202 def selection_clear(self):
2203 """Clear the selection if it is in this widget."""
2204 self.tk.call(self._w, 'selection', 'clear')
2205 select_clear = selection_clear
2206 def selection_from(self, index):
2207 """Set the fixed end of a selection to INDEX."""
2208 self.tk.call(self._w, 'selection', 'from', index)
2209 select_from = selection_from
2210 def selection_present(self):
2211 """Return whether the widget has the selection."""
2212 return self.tk.getboolean(
2213 self.tk.call(self._w, 'selection', 'present'))
2214 select_present = selection_present
2215 def selection_range(self, start, end):
2216 """Set the selection from START to END (not included)."""
2217 self.tk.call(self._w, 'selection', 'range', start, end)
2218 select_range = selection_range
2219 def selection_to(self, index):
2220 """Set the variable end of a selection to INDEX."""
2221 self.tk.call(self._w, 'selection', 'to', index)
2222 select_to = selection_to
2223 def xview(self, index):
2224 """Query and change horizontal position of the view."""
2225 self.tk.call(self._w, 'xview', index)
2226 def xview_moveto(self, fraction):
2227 """Adjust the view in the window so that FRACTION of the
2228 total width of the entry is off-screen to the left."""
2229 self.tk.call(self._w, 'xview', 'moveto', fraction)
2230 def xview_scroll(self, number, what):
2231 """Shift the x-view according to NUMBER which is measured in "units" or "pages" (WHAT)."""
2232 self.tk.call(self._w, 'xview', 'scroll', number, what)
Guido van Rossum18468821994-06-20 07:49:28 +00002233
2234class Frame(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002235 """Frame widget which may contain other widgets and can have a 3D border."""
2236 def __init__(self, master=None, cnf={}, **kw):
2237 """Construct a frame widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002238
Fredrik Lundh06d28152000-08-09 18:03:12 +00002239 Valid resource names: background, bd, bg, borderwidth, class,
2240 colormap, container, cursor, height, highlightbackground,
2241 highlightcolor, highlightthickness, relief, takefocus, visual, width."""
2242 cnf = _cnfmerge((cnf, kw))
2243 extra = ()
2244 if cnf.has_key('class_'):
2245 extra = ('-class', cnf['class_'])
2246 del cnf['class_']
2247 elif cnf.has_key('class'):
2248 extra = ('-class', cnf['class'])
2249 del cnf['class']
2250 Widget.__init__(self, master, 'frame', cnf, {}, extra)
Guido van Rossum18468821994-06-20 07:49:28 +00002251
2252class Label(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002253 """Label widget which can display text and bitmaps."""
2254 def __init__(self, master=None, cnf={}, **kw):
2255 """Construct a label widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002256
Fredrik Lundh06d28152000-08-09 18:03:12 +00002257 Valid resource names: anchor, background, bd, bg, bitmap,
2258 borderwidth, cursor, fg, font, foreground, height,
2259 highlightbackground, highlightcolor, highlightthickness, image,
2260 justify, padx, pady, relief, takefocus, text, textvariable,
2261 underline, width, wraplength."""
2262 Widget.__init__(self, master, 'label', cnf, kw)
Guido van Rossum761c5ab1995-07-14 15:29:10 +00002263
Guido van Rossum18468821994-06-20 07:49:28 +00002264class Listbox(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002265 """Listbox widget which can display a list of strings."""
2266 def __init__(self, master=None, cnf={}, **kw):
2267 """Construct a listbox widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002268
Fredrik Lundh06d28152000-08-09 18:03:12 +00002269 Valid resource names: background, bd, bg, borderwidth, cursor,
2270 exportselection, fg, font, foreground, height, highlightbackground,
2271 highlightcolor, highlightthickness, relief, selectbackground,
2272 selectborderwidth, selectforeground, selectmode, setgrid, takefocus,
2273 width, xscrollcommand, yscrollcommand, listvariable."""
2274 Widget.__init__(self, master, 'listbox', cnf, kw)
2275 def activate(self, index):
2276 """Activate item identified by INDEX."""
2277 self.tk.call(self._w, 'activate', index)
2278 def bbox(self, *args):
2279 """Return a tuple of X1,Y1,X2,Y2 coordinates for a rectangle
2280 which encloses the item identified by index in ARGS."""
2281 return self._getints(
2282 self.tk.call((self._w, 'bbox') + args)) or None
2283 def curselection(self):
2284 """Return list of indices of currently selected item."""
2285 # XXX Ought to apply self._getints()...
2286 return self.tk.splitlist(self.tk.call(
2287 self._w, 'curselection'))
2288 def delete(self, first, last=None):
2289 """Delete items from FIRST to LAST (not included)."""
2290 self.tk.call(self._w, 'delete', first, last)
2291 def get(self, first, last=None):
2292 """Get list of items from FIRST to LAST (not included)."""
2293 if last:
2294 return self.tk.splitlist(self.tk.call(
2295 self._w, 'get', first, last))
2296 else:
2297 return self.tk.call(self._w, 'get', first)
2298 def index(self, index):
2299 """Return index of item identified with INDEX."""
2300 i = self.tk.call(self._w, 'index', index)
2301 if i == 'none': return None
2302 return getint(i)
2303 def insert(self, index, *elements):
2304 """Insert ELEMENTS at INDEX."""
2305 self.tk.call((self._w, 'insert', index) + elements)
2306 def nearest(self, y):
2307 """Get index of item which is nearest to y coordinate Y."""
2308 return getint(self.tk.call(
2309 self._w, 'nearest', y))
2310 def scan_mark(self, x, y):
2311 """Remember the current X, Y coordinates."""
2312 self.tk.call(self._w, 'scan', 'mark', x, y)
2313 def scan_dragto(self, x, y):
2314 """Adjust the view of the listbox to 10 times the
2315 difference between X and Y and the coordinates given in
2316 scan_mark."""
2317 self.tk.call(self._w, 'scan', 'dragto', x, y)
2318 def see(self, index):
2319 """Scroll such that INDEX is visible."""
2320 self.tk.call(self._w, 'see', index)
2321 def selection_anchor(self, index):
2322 """Set the fixed end oft the selection to INDEX."""
2323 self.tk.call(self._w, 'selection', 'anchor', index)
2324 select_anchor = selection_anchor
2325 def selection_clear(self, first, last=None):
2326 """Clear the selection from FIRST to LAST (not included)."""
2327 self.tk.call(self._w,
2328 'selection', 'clear', first, last)
2329 select_clear = selection_clear
2330 def selection_includes(self, index):
2331 """Return 1 if INDEX is part of the selection."""
2332 return self.tk.getboolean(self.tk.call(
2333 self._w, 'selection', 'includes', index))
2334 select_includes = selection_includes
2335 def selection_set(self, first, last=None):
2336 """Set the selection from FIRST to LAST (not included) without
2337 changing the currently selected elements."""
2338 self.tk.call(self._w, 'selection', 'set', first, last)
2339 select_set = selection_set
2340 def size(self):
2341 """Return the number of elements in the listbox."""
2342 return getint(self.tk.call(self._w, 'size'))
2343 def xview(self, *what):
2344 """Query and change horizontal position of the view."""
2345 if not what:
2346 return self._getdoubles(self.tk.call(self._w, 'xview'))
2347 self.tk.call((self._w, 'xview') + what)
2348 def xview_moveto(self, fraction):
2349 """Adjust the view in the window so that FRACTION of the
2350 total width of the entry is off-screen to the left."""
2351 self.tk.call(self._w, 'xview', 'moveto', fraction)
2352 def xview_scroll(self, number, what):
2353 """Shift the x-view according to NUMBER which is measured in "units" or "pages" (WHAT)."""
2354 self.tk.call(self._w, 'xview', 'scroll', number, what)
2355 def yview(self, *what):
2356 """Query and change vertical position of the view."""
2357 if not what:
2358 return self._getdoubles(self.tk.call(self._w, 'yview'))
2359 self.tk.call((self._w, 'yview') + what)
2360 def yview_moveto(self, fraction):
2361 """Adjust the view in the window so that FRACTION of the
2362 total width of the entry is off-screen to the top."""
2363 self.tk.call(self._w, 'yview', 'moveto', fraction)
2364 def yview_scroll(self, number, what):
2365 """Shift the y-view according to NUMBER which is measured in "units" or "pages" (WHAT)."""
2366 self.tk.call(self._w, 'yview', 'scroll', number, what)
Guido van Rossum18468821994-06-20 07:49:28 +00002367
2368class Menu(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002369 """Menu widget which allows to display menu bars, pull-down menus and pop-up menus."""
2370 def __init__(self, master=None, cnf={}, **kw):
2371 """Construct menu widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002372
Fredrik Lundh06d28152000-08-09 18:03:12 +00002373 Valid resource names: activebackground, activeborderwidth,
2374 activeforeground, background, bd, bg, borderwidth, cursor,
2375 disabledforeground, fg, font, foreground, postcommand, relief,
2376 selectcolor, takefocus, tearoff, tearoffcommand, title, type."""
2377 Widget.__init__(self, master, 'menu', cnf, kw)
2378 def tk_bindForTraversal(self):
2379 pass # obsolete since Tk 4.0
2380 def tk_mbPost(self):
2381 self.tk.call('tk_mbPost', self._w)
2382 def tk_mbUnpost(self):
2383 self.tk.call('tk_mbUnpost')
2384 def tk_traverseToMenu(self, char):
2385 self.tk.call('tk_traverseToMenu', self._w, char)
2386 def tk_traverseWithinMenu(self, char):
2387 self.tk.call('tk_traverseWithinMenu', self._w, char)
2388 def tk_getMenuButtons(self):
2389 return self.tk.call('tk_getMenuButtons', self._w)
2390 def tk_nextMenu(self, count):
2391 self.tk.call('tk_nextMenu', count)
2392 def tk_nextMenuEntry(self, count):
2393 self.tk.call('tk_nextMenuEntry', count)
2394 def tk_invokeMenu(self):
2395 self.tk.call('tk_invokeMenu', self._w)
2396 def tk_firstMenu(self):
2397 self.tk.call('tk_firstMenu', self._w)
2398 def tk_mbButtonDown(self):
2399 self.tk.call('tk_mbButtonDown', self._w)
2400 def tk_popup(self, x, y, entry=""):
2401 """Post the menu at position X,Y with entry ENTRY."""
2402 self.tk.call('tk_popup', self._w, x, y, entry)
2403 def activate(self, index):
2404 """Activate entry at INDEX."""
2405 self.tk.call(self._w, 'activate', index)
2406 def add(self, itemType, cnf={}, **kw):
2407 """Internal function."""
2408 self.tk.call((self._w, 'add', itemType) +
2409 self._options(cnf, kw))
2410 def add_cascade(self, cnf={}, **kw):
2411 """Add hierarchical menu item."""
2412 self.add('cascade', cnf or kw)
2413 def add_checkbutton(self, cnf={}, **kw):
2414 """Add checkbutton menu item."""
2415 self.add('checkbutton', cnf or kw)
2416 def add_command(self, cnf={}, **kw):
2417 """Add command menu item."""
2418 self.add('command', cnf or kw)
2419 def add_radiobutton(self, cnf={}, **kw):
2420 """Addd radio menu item."""
2421 self.add('radiobutton', cnf or kw)
2422 def add_separator(self, cnf={}, **kw):
2423 """Add separator."""
2424 self.add('separator', cnf or kw)
2425 def insert(self, index, itemType, cnf={}, **kw):
2426 """Internal function."""
2427 self.tk.call((self._w, 'insert', index, itemType) +
2428 self._options(cnf, kw))
2429 def insert_cascade(self, index, cnf={}, **kw):
2430 """Add hierarchical menu item at INDEX."""
2431 self.insert(index, 'cascade', cnf or kw)
2432 def insert_checkbutton(self, index, cnf={}, **kw):
2433 """Add checkbutton menu item at INDEX."""
2434 self.insert(index, 'checkbutton', cnf or kw)
2435 def insert_command(self, index, cnf={}, **kw):
2436 """Add command menu item at INDEX."""
2437 self.insert(index, 'command', cnf or kw)
2438 def insert_radiobutton(self, index, cnf={}, **kw):
2439 """Addd radio menu item at INDEX."""
2440 self.insert(index, 'radiobutton', cnf or kw)
2441 def insert_separator(self, index, cnf={}, **kw):
2442 """Add separator at INDEX."""
2443 self.insert(index, 'separator', cnf or kw)
2444 def delete(self, index1, index2=None):
2445 """Delete menu items between INDEX1 and INDEX2 (not included)."""
2446 self.tk.call(self._w, 'delete', index1, index2)
2447 def entrycget(self, index, option):
2448 """Return the resource value of an menu item for OPTION at INDEX."""
2449 return self.tk.call(self._w, 'entrycget', index, '-' + option)
2450 def entryconfigure(self, index, cnf=None, **kw):
2451 """Configure a menu item at INDEX."""
2452 if cnf is None and not kw:
2453 cnf = {}
2454 for x in self.tk.split(self.tk.call(
2455 (self._w, 'entryconfigure', index))):
2456 cnf[x[0][1:]] = (x[0][1:],) + x[1:]
2457 return cnf
2458 if type(cnf) == StringType and not kw:
2459 x = self.tk.split(self.tk.call(
2460 (self._w, 'entryconfigure', index, '-'+cnf)))
2461 return (x[0][1:],) + x[1:]
2462 self.tk.call((self._w, 'entryconfigure', index)
2463 + self._options(cnf, kw))
2464 entryconfig = entryconfigure
2465 def index(self, index):
2466 """Return the index of a menu item identified by INDEX."""
2467 i = self.tk.call(self._w, 'index', index)
2468 if i == 'none': return None
2469 return getint(i)
2470 def invoke(self, index):
2471 """Invoke a menu item identified by INDEX and execute
2472 the associated command."""
2473 return self.tk.call(self._w, 'invoke', index)
2474 def post(self, x, y):
2475 """Display a menu at position X,Y."""
2476 self.tk.call(self._w, 'post', x, y)
2477 def type(self, index):
2478 """Return the type of the menu item at INDEX."""
2479 return self.tk.call(self._w, 'type', index)
2480 def unpost(self):
2481 """Unmap a menu."""
2482 self.tk.call(self._w, 'unpost')
2483 def yposition(self, index):
2484 """Return the y-position of the topmost pixel of the menu item at INDEX."""
2485 return getint(self.tk.call(
2486 self._w, 'yposition', index))
Guido van Rossum18468821994-06-20 07:49:28 +00002487
2488class Menubutton(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002489 """Menubutton widget, obsolete since Tk8.0."""
2490 def __init__(self, master=None, cnf={}, **kw):
2491 Widget.__init__(self, master, 'menubutton', cnf, kw)
Guido van Rossum18468821994-06-20 07:49:28 +00002492
2493class Message(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002494 """Message widget to display multiline text. Obsolete since Label does it too."""
2495 def __init__(self, master=None, cnf={}, **kw):
2496 Widget.__init__(self, master, 'message', cnf, kw)
Guido van Rossum18468821994-06-20 07:49:28 +00002497
2498class Radiobutton(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002499 """Radiobutton widget which shows only one of several buttons in on-state."""
2500 def __init__(self, master=None, cnf={}, **kw):
2501 """Construct a radiobutton widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002502
Fredrik Lundh06d28152000-08-09 18:03:12 +00002503 Valid resource names: activebackground, activeforeground, anchor,
2504 background, bd, bg, bitmap, borderwidth, command, cursor,
2505 disabledforeground, fg, font, foreground, height,
2506 highlightbackground, highlightcolor, highlightthickness, image,
2507 indicatoron, justify, padx, pady, relief, selectcolor, selectimage,
2508 state, takefocus, text, textvariable, underline, value, variable,
2509 width, wraplength."""
2510 Widget.__init__(self, master, 'radiobutton', cnf, kw)
2511 def deselect(self):
2512 """Put the button in off-state."""
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002513
Fredrik Lundh06d28152000-08-09 18:03:12 +00002514 self.tk.call(self._w, 'deselect')
2515 def flash(self):
2516 """Flash the button."""
2517 self.tk.call(self._w, 'flash')
2518 def invoke(self):
2519 """Toggle the button and invoke a command if given as resource."""
2520 return self.tk.call(self._w, 'invoke')
2521 def select(self):
2522 """Put the button in on-state."""
2523 self.tk.call(self._w, 'select')
Guido van Rossum18468821994-06-20 07:49:28 +00002524
2525class Scale(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002526 """Scale widget which can display a numerical scale."""
2527 def __init__(self, master=None, cnf={}, **kw):
2528 """Construct a scale widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002529
Fredrik Lundh06d28152000-08-09 18:03:12 +00002530 Valid resource names: activebackground, background, bigincrement, bd,
2531 bg, borderwidth, command, cursor, digits, fg, font, foreground, from,
2532 highlightbackground, highlightcolor, highlightthickness, label,
2533 length, orient, relief, repeatdelay, repeatinterval, resolution,
2534 showvalue, sliderlength, sliderrelief, state, takefocus,
2535 tickinterval, to, troughcolor, variable, width."""
2536 Widget.__init__(self, master, 'scale', cnf, kw)
2537 def get(self):
2538 """Get the current value as integer or float."""
2539 value = self.tk.call(self._w, 'get')
2540 try:
2541 return getint(value)
2542 except ValueError:
2543 return getdouble(value)
2544 def set(self, value):
2545 """Set the value to VALUE."""
2546 self.tk.call(self._w, 'set', value)
2547 def coords(self, value=None):
2548 """Return a tuple (X,Y) of the point along the centerline of the
2549 trough that corresponds to VALUE or the current value if None is
2550 given."""
2551
2552 return self._getints(self.tk.call(self._w, 'coords', value))
2553 def identify(self, x, y):
2554 """Return where the point X,Y lies. Valid return values are "slider",
2555 "though1" and "though2"."""
2556 return self.tk.call(self._w, 'identify', x, y)
Guido van Rossum18468821994-06-20 07:49:28 +00002557
2558class Scrollbar(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002559 """Scrollbar widget which displays a slider at a certain position."""
2560 def __init__(self, master=None, cnf={}, **kw):
2561 """Construct a scrollbar widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002562
Fredrik Lundh06d28152000-08-09 18:03:12 +00002563 Valid resource names: activebackground, activerelief,
2564 background, bd, bg, borderwidth, command, cursor,
2565 elementborderwidth, highlightbackground,
2566 highlightcolor, highlightthickness, jump, orient,
2567 relief, repeatdelay, repeatinterval, takefocus,
2568 troughcolor, width."""
2569 Widget.__init__(self, master, 'scrollbar', cnf, kw)
2570 def activate(self, index):
2571 """Display the element at INDEX with activebackground and activerelief.
2572 INDEX can be "arrow1","slider" or "arrow2"."""
2573 self.tk.call(self._w, 'activate', index)
2574 def delta(self, deltax, deltay):
2575 """Return the fractional change of the scrollbar setting if it
2576 would be moved by DELTAX or DELTAY pixels."""
2577 return getdouble(
2578 self.tk.call(self._w, 'delta', deltax, deltay))
2579 def fraction(self, x, y):
2580 """Return the fractional value which corresponds to a slider
2581 position of X,Y."""
2582 return getdouble(self.tk.call(self._w, 'fraction', x, y))
2583 def identify(self, x, y):
2584 """Return the element under position X,Y as one of
2585 "arrow1","slider","arrow2" or ""."""
2586 return self.tk.call(self._w, 'identify', x, y)
2587 def get(self):
2588 """Return the current fractional values (upper and lower end)
2589 of the slider position."""
2590 return self._getdoubles(self.tk.call(self._w, 'get'))
2591 def set(self, *args):
2592 """Set the fractional values of the slider position (upper and
2593 lower ends as value between 0 and 1)."""
2594 self.tk.call((self._w, 'set') + args)
Guido van Rossum18468821994-06-20 07:49:28 +00002595
2596class Text(Widget):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002597 """Text widget which can display text in various forms."""
2598 # XXX Add dump()
2599 def __init__(self, master=None, cnf={}, **kw):
2600 """Construct a text widget with the parent MASTER.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002601
Fredrik Lundh06d28152000-08-09 18:03:12 +00002602 Valid resource names: background, bd, bg, borderwidth, cursor,
2603 exportselection, fg, font, foreground, height,
2604 highlightbackground, highlightcolor, highlightthickness,
2605 insertbackground, insertborderwidth, insertofftime,
2606 insertontime, insertwidth, padx, pady, relief,
2607 selectbackground, selectborderwidth, selectforeground,
2608 setgrid, spacing1, spacing2, spacing3, state, tabs, takefocus,
2609 width, wrap, xscrollcommand, yscrollcommand."""
2610 Widget.__init__(self, master, 'text', cnf, kw)
2611 def bbox(self, *args):
2612 """Return a tuple of (x,y,width,height) which gives the bounding
2613 box of the visible part of the character at the index in ARGS."""
2614 return self._getints(
2615 self.tk.call((self._w, 'bbox') + args)) or None
2616 def tk_textSelectTo(self, index):
2617 self.tk.call('tk_textSelectTo', self._w, index)
2618 def tk_textBackspace(self):
2619 self.tk.call('tk_textBackspace', self._w)
2620 def tk_textIndexCloser(self, a, b, c):
2621 self.tk.call('tk_textIndexCloser', self._w, a, b, c)
2622 def tk_textResetAnchor(self, index):
2623 self.tk.call('tk_textResetAnchor', self._w, index)
2624 def compare(self, index1, op, index2):
2625 """Return whether between index INDEX1 and index INDEX2 the
2626 relation OP is satisfied. OP is one of <, <=, ==, >=, >, or !=."""
2627 return self.tk.getboolean(self.tk.call(
2628 self._w, 'compare', index1, op, index2))
2629 def debug(self, boolean=None):
2630 """Turn on the internal consistency checks of the B-Tree inside the text
2631 widget according to BOOLEAN."""
2632 return self.tk.getboolean(self.tk.call(
2633 self._w, 'debug', boolean))
2634 def delete(self, index1, index2=None):
2635 """Delete the characters between INDEX1 and INDEX2 (not included)."""
2636 self.tk.call(self._w, 'delete', index1, index2)
2637 def dlineinfo(self, index):
2638 """Return tuple (x,y,width,height,baseline) giving the bounding box
2639 and baseline position of the visible part of the line containing
2640 the character at INDEX."""
2641 return self._getints(self.tk.call(self._w, 'dlineinfo', index))
2642 def get(self, index1, index2=None):
2643 """Return the text from INDEX1 to INDEX2 (not included)."""
2644 return self.tk.call(self._w, 'get', index1, index2)
2645 # (Image commands are new in 8.0)
2646 def image_cget(self, index, option):
2647 """Return the value of OPTION of an embedded image at INDEX."""
2648 if option[:1] != "-":
2649 option = "-" + option
2650 if option[-1:] == "_":
2651 option = option[:-1]
2652 return self.tk.call(self._w, "image", "cget", index, option)
2653 def image_configure(self, index, cnf={}, **kw):
2654 """Configure an embedded image at INDEX."""
2655 if not cnf and not kw:
2656 cnf = {}
2657 for x in self.tk.split(
2658 self.tk.call(
2659 self._w, "image", "configure", index)):
2660 cnf[x[0][1:]] = (x[0][1:],) + x[1:]
2661 return cnf
2662 apply(self.tk.call,
2663 (self._w, "image", "configure", index)
2664 + self._options(cnf, kw))
2665 def image_create(self, index, cnf={}, **kw):
2666 """Create an embedded image at INDEX."""
2667 return apply(self.tk.call,
2668 (self._w, "image", "create", index)
2669 + self._options(cnf, kw))
2670 def image_names(self):
2671 """Return all names of embedded images in this widget."""
2672 return self.tk.call(self._w, "image", "names")
2673 def index(self, index):
2674 """Return the index in the form line.char for INDEX."""
2675 return self.tk.call(self._w, 'index', index)
2676 def insert(self, index, chars, *args):
2677 """Insert CHARS before the characters at INDEX. An additional
2678 tag can be given in ARGS. Additional CHARS and tags can follow in ARGS."""
2679 self.tk.call((self._w, 'insert', index, chars) + args)
2680 def mark_gravity(self, markName, direction=None):
2681 """Change the gravity of a mark MARKNAME to DIRECTION (LEFT or RIGHT).
2682 Return the current value if None is given for DIRECTION."""
2683 return self.tk.call(
2684 (self._w, 'mark', 'gravity', markName, direction))
2685 def mark_names(self):
2686 """Return all mark names."""
2687 return self.tk.splitlist(self.tk.call(
2688 self._w, 'mark', 'names'))
2689 def mark_set(self, markName, index):
2690 """Set mark MARKNAME before the character at INDEX."""
2691 self.tk.call(self._w, 'mark', 'set', markName, index)
2692 def mark_unset(self, *markNames):
2693 """Delete all marks in MARKNAMES."""
2694 self.tk.call((self._w, 'mark', 'unset') + markNames)
2695 def mark_next(self, index):
2696 """Return the name of the next mark after INDEX."""
2697 return self.tk.call(self._w, 'mark', 'next', index) or None
2698 def mark_previous(self, index):
2699 """Return the name of the previous mark before INDEX."""
2700 return self.tk.call(self._w, 'mark', 'previous', index) or None
2701 def scan_mark(self, x, y):
2702 """Remember the current X, Y coordinates."""
2703 self.tk.call(self._w, 'scan', 'mark', x, y)
2704 def scan_dragto(self, x, y):
2705 """Adjust the view of the text to 10 times the
2706 difference between X and Y and the coordinates given in
2707 scan_mark."""
2708 self.tk.call(self._w, 'scan', 'dragto', x, y)
2709 def search(self, pattern, index, stopindex=None,
2710 forwards=None, backwards=None, exact=None,
2711 regexp=None, nocase=None, count=None):
2712 """Search PATTERN beginning from INDEX until STOPINDEX.
2713 Return the index of the first character of a match or an empty string."""
2714 args = [self._w, 'search']
2715 if forwards: args.append('-forwards')
2716 if backwards: args.append('-backwards')
2717 if exact: args.append('-exact')
2718 if regexp: args.append('-regexp')
2719 if nocase: args.append('-nocase')
2720 if count: args.append('-count'); args.append(count)
2721 if pattern[0] == '-': args.append('--')
2722 args.append(pattern)
2723 args.append(index)
2724 if stopindex: args.append(stopindex)
2725 return self.tk.call(tuple(args))
2726 def see(self, index):
2727 """Scroll such that the character at INDEX is visible."""
2728 self.tk.call(self._w, 'see', index)
2729 def tag_add(self, tagName, index1, *args):
2730 """Add tag TAGNAME to all characters between INDEX1 and index2 in ARGS.
2731 Additional pairs of indices may follow in ARGS."""
2732 self.tk.call(
2733 (self._w, 'tag', 'add', tagName, index1) + args)
2734 def tag_unbind(self, tagName, sequence, funcid=None):
2735 """Unbind for all characters with TAGNAME for event SEQUENCE the
2736 function identified with FUNCID."""
2737 self.tk.call(self._w, 'tag', 'bind', tagName, sequence, '')
2738 if funcid:
2739 self.deletecommand(funcid)
2740 def tag_bind(self, tagName, sequence, func, add=None):
2741 """Bind to all characters with TAGNAME at event SEQUENCE a call to function FUNC.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002742
Fredrik Lundh06d28152000-08-09 18:03:12 +00002743 An additional boolean parameter ADD specifies whether FUNC will be
2744 called additionally to the other bound function or whether it will
2745 replace the previous function. See bind for the return value."""
2746 return self._bind((self._w, 'tag', 'bind', tagName),
2747 sequence, func, add)
2748 def tag_cget(self, tagName, option):
2749 """Return the value of OPTION for tag TAGNAME."""
2750 if option[:1] != '-':
2751 option = '-' + option
2752 if option[-1:] == '_':
2753 option = option[:-1]
2754 return self.tk.call(self._w, 'tag', 'cget', tagName, option)
2755 def tag_configure(self, tagName, cnf={}, **kw):
2756 """Configure a tag TAGNAME."""
2757 if type(cnf) == StringType:
2758 x = self.tk.split(self.tk.call(
2759 self._w, 'tag', 'configure', tagName, '-'+cnf))
2760 return (x[0][1:],) + x[1:]
2761 self.tk.call(
2762 (self._w, 'tag', 'configure', tagName)
2763 + self._options(cnf, kw))
2764 tag_config = tag_configure
2765 def tag_delete(self, *tagNames):
2766 """Delete all tags in TAGNAMES."""
2767 self.tk.call((self._w, 'tag', 'delete') + tagNames)
2768 def tag_lower(self, tagName, belowThis=None):
2769 """Change the priority of tag TAGNAME such that it is lower
2770 than the priority of BELOWTHIS."""
2771 self.tk.call(self._w, 'tag', 'lower', tagName, belowThis)
2772 def tag_names(self, index=None):
2773 """Return a list of all tag names."""
2774 return self.tk.splitlist(
2775 self.tk.call(self._w, 'tag', 'names', index))
2776 def tag_nextrange(self, tagName, index1, index2=None):
2777 """Return a list of start and end index for the first sequence of
2778 characters between INDEX1 and INDEX2 which all have tag TAGNAME.
2779 The text is searched forward from INDEX1."""
2780 return self.tk.splitlist(self.tk.call(
2781 self._w, 'tag', 'nextrange', tagName, index1, index2))
2782 def tag_prevrange(self, tagName, index1, index2=None):
2783 """Return a list of start and end index for the first sequence of
2784 characters between INDEX1 and INDEX2 which all have tag TAGNAME.
2785 The text is searched backwards from INDEX1."""
2786 return self.tk.splitlist(self.tk.call(
2787 self._w, 'tag', 'prevrange', tagName, index1, index2))
2788 def tag_raise(self, tagName, aboveThis=None):
2789 """Change the priority of tag TAGNAME such that it is higher
2790 than the priority of ABOVETHIS."""
2791 self.tk.call(
2792 self._w, 'tag', 'raise', tagName, aboveThis)
2793 def tag_ranges(self, tagName):
2794 """Return a list of ranges of text which have tag TAGNAME."""
2795 return self.tk.splitlist(self.tk.call(
2796 self._w, 'tag', 'ranges', tagName))
2797 def tag_remove(self, tagName, index1, index2=None):
2798 """Remove tag TAGNAME from all characters between INDEX1 and INDEX2."""
2799 self.tk.call(
2800 self._w, 'tag', 'remove', tagName, index1, index2)
2801 def window_cget(self, index, option):
2802 """Return the value of OPTION of an embedded window at INDEX."""
2803 if option[:1] != '-':
2804 option = '-' + option
2805 if option[-1:] == '_':
2806 option = option[:-1]
2807 return self.tk.call(self._w, 'window', 'cget', index, option)
2808 def window_configure(self, index, cnf={}, **kw):
2809 """Configure an embedded window at INDEX."""
2810 if type(cnf) == StringType:
2811 x = self.tk.split(self.tk.call(
2812 self._w, 'window', 'configure',
2813 index, '-'+cnf))
2814 return (x[0][1:],) + x[1:]
2815 self.tk.call(
2816 (self._w, 'window', 'configure', index)
2817 + self._options(cnf, kw))
2818 window_config = window_configure
2819 def window_create(self, index, cnf={}, **kw):
2820 """Create a window at INDEX."""
2821 self.tk.call(
2822 (self._w, 'window', 'create', index)
2823 + self._options(cnf, kw))
2824 def window_names(self):
2825 """Return all names of embedded windows in this widget."""
2826 return self.tk.splitlist(
2827 self.tk.call(self._w, 'window', 'names'))
2828 def xview(self, *what):
2829 """Query and change horizontal position of the view."""
2830 if not what:
2831 return self._getdoubles(self.tk.call(self._w, 'xview'))
2832 self.tk.call((self._w, 'xview') + what)
Fredrik Lundh5bd2cd62000-08-09 18:29:51 +00002833 def xview_moveto(self, fraction):
2834 """Adjusts the view in the window so that FRACTION of the
2835 total width of the canvas is off-screen to the left."""
2836 self.tk.call(self._w, 'xview', 'moveto', fraction)
2837 def xview_scroll(self, number, what):
2838 """Shift the x-view according to NUMBER which is measured
2839 in "units" or "pages" (WHAT)."""
2840 self.tk.call(self._w, 'xview', 'scroll', number, what)
2841 def yview(self, *args):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002842 """Query and change vertical position of the view."""
Fredrik Lundh5bd2cd62000-08-09 18:29:51 +00002843 if not args:
Fredrik Lundh06d28152000-08-09 18:03:12 +00002844 return self._getdoubles(self.tk.call(self._w, 'yview'))
Fredrik Lundh5bd2cd62000-08-09 18:29:51 +00002845 self.tk.call((self._w, 'yview') + args)
2846 def yview_moveto(self, fraction):
2847 """Adjusts the view in the window so that FRACTION of the
2848 total height of the canvas is off-screen to the top."""
2849 self.tk.call(self._w, 'yview', 'moveto', fraction)
2850 def yview_scroll(self, number, what):
2851 """Shift the y-view according to NUMBER which is measured
2852 in "units" or "pages" (WHAT)."""
2853 self.tk.call(self._w, 'yview', 'scroll', number, what)
Fredrik Lundh06d28152000-08-09 18:03:12 +00002854 def yview_pickplace(self, *what):
2855 """Obsolete function, use see."""
2856 self.tk.call((self._w, 'yview', '-pickplace') + what)
Guido van Rossum18468821994-06-20 07:49:28 +00002857
Guido van Rossum28574b51996-10-21 15:16:51 +00002858class _setit:
Fredrik Lundh06d28152000-08-09 18:03:12 +00002859 """Internal class. It wraps the command in the widget OptionMenu."""
2860 def __init__(self, var, value, callback=None):
2861 self.__value = value
2862 self.__var = var
2863 self.__callback = callback
2864 def __call__(self, *args):
2865 self.__var.set(self.__value)
2866 if self.__callback:
2867 apply(self.__callback, (self.__value,)+args)
Guido van Rossum28574b51996-10-21 15:16:51 +00002868
2869class OptionMenu(Menubutton):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002870 """OptionMenu which allows the user to select a value from a menu."""
2871 def __init__(self, master, variable, value, *values, **kwargs):
2872 """Construct an optionmenu widget with the parent MASTER, with
2873 the resource textvariable set to VARIABLE, the initially selected
2874 value VALUE, the other menu values VALUES and an additional
2875 keyword argument command."""
2876 kw = {"borderwidth": 2, "textvariable": variable,
2877 "indicatoron": 1, "relief": RAISED, "anchor": "c",
2878 "highlightthickness": 2}
2879 Widget.__init__(self, master, "menubutton", kw)
2880 self.widgetName = 'tk_optionMenu'
2881 menu = self.__menu = Menu(self, name="menu", tearoff=0)
2882 self.menuname = menu._w
2883 # 'command' is the only supported keyword
2884 callback = kwargs.get('command')
2885 if kwargs.has_key('command'):
2886 del kwargs['command']
2887 if kwargs:
2888 raise TclError, 'unknown option -'+kwargs.keys()[0]
2889 menu.add_command(label=value,
2890 command=_setit(variable, value, callback))
2891 for v in values:
2892 menu.add_command(label=v,
2893 command=_setit(variable, v, callback))
2894 self["menu"] = menu
Guido van Rossum28574b51996-10-21 15:16:51 +00002895
Fredrik Lundh06d28152000-08-09 18:03:12 +00002896 def __getitem__(self, name):
2897 if name == 'menu':
2898 return self.__menu
2899 return Widget.__getitem__(self, name)
Guido van Rossum28574b51996-10-21 15:16:51 +00002900
Fredrik Lundh06d28152000-08-09 18:03:12 +00002901 def destroy(self):
2902 """Destroy this widget and the associated menu."""
2903 Menubutton.destroy(self)
2904 self.__menu = None
Guido van Rossumbf4d8f91995-09-01 20:35:37 +00002905
Guido van Rossum35f67fb1995-08-04 03:50:29 +00002906class Image:
Fredrik Lundh06d28152000-08-09 18:03:12 +00002907 """Base class for images."""
2908 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:
2916 name = `id(self)`
2917 # The following is needed for systems where id(x)
2918 # can return a negative number, such as Linux/m68k:
2919 if name[0] == '-': name = '_' + name[1:]
2920 if kw and cnf: cnf = _cnfmerge((cnf, kw))
2921 elif kw: cnf = kw
2922 options = ()
2923 for k, v in cnf.items():
2924 if callable(v):
2925 v = self._register(v)
2926 options = options + ('-'+k, v)
2927 self.tk.call(('image', 'create', imgtype, name,) + options)
2928 self.name = name
2929 def __str__(self): return self.name
2930 def __del__(self):
2931 if self.name:
2932 try:
2933 self.tk.call('image', 'delete', self.name)
2934 except TclError:
2935 # May happen if the root was destroyed
2936 pass
2937 def __setitem__(self, key, value):
2938 self.tk.call(self.name, 'configure', '-'+key, value)
2939 def __getitem__(self, key):
2940 return self.tk.call(self.name, 'configure', '-'+key)
2941 def configure(self, **kw):
2942 """Configure the image."""
2943 res = ()
2944 for k, v in _cnfmerge(kw).items():
2945 if v is not None:
2946 if k[-1] == '_': k = k[:-1]
2947 if callable(v):
2948 v = self._register(v)
2949 res = res + ('-'+k, v)
2950 self.tk.call((self.name, 'config') + res)
2951 config = configure
2952 def height(self):
2953 """Return the height of the image."""
2954 return getint(
2955 self.tk.call('image', 'height', self.name))
2956 def type(self):
2957 """Return the type of the imgage, e.g. "photo" or "bitmap"."""
2958 return self.tk.call('image', 'type', self.name)
2959 def width(self):
2960 """Return the width of the image."""
2961 return getint(
2962 self.tk.call('image', 'width', self.name))
Guido van Rossum35f67fb1995-08-04 03:50:29 +00002963
2964class PhotoImage(Image):
Fredrik Lundh06d28152000-08-09 18:03:12 +00002965 """Widget which can display colored images in GIF, PPM/PGM format."""
2966 def __init__(self, name=None, cnf={}, master=None, **kw):
2967 """Create an image with NAME.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00002968
Fredrik Lundh06d28152000-08-09 18:03:12 +00002969 Valid resource names: data, format, file, gamma, height, palette,
2970 width."""
2971 apply(Image.__init__, (self, 'photo', name, cnf, master), kw)
2972 def blank(self):
2973 """Display a transparent image."""
2974 self.tk.call(self.name, 'blank')
2975 def cget(self, option):
2976 """Return the value of OPTION."""
2977 return self.tk.call(self.name, 'cget', '-' + option)
2978 # XXX config
2979 def __getitem__(self, key):
2980 return self.tk.call(self.name, 'cget', '-' + key)
2981 # XXX copy -from, -to, ...?
2982 def copy(self):
2983 """Return a new PhotoImage with the same image as this widget."""
2984 destImage = PhotoImage()
2985 self.tk.call(destImage, 'copy', self.name)
2986 return destImage
2987 def zoom(self,x,y=''):
2988 """Return a new PhotoImage with the same image as this widget
2989 but zoom it with X and Y."""
2990 destImage = PhotoImage()
2991 if y=='': y=x
2992 self.tk.call(destImage, 'copy', self.name, '-zoom',x,y)
2993 return destImage
2994 def subsample(self,x,y=''):
2995 """Return a new PhotoImage based on the same image as this widget
2996 but use only every Xth or Yth pixel."""
2997 destImage = PhotoImage()
2998 if y=='': y=x
2999 self.tk.call(destImage, 'copy', self.name, '-subsample',x,y)
3000 return destImage
3001 def get(self, x, y):
3002 """Return the color (red, green, blue) of the pixel at X,Y."""
3003 return self.tk.call(self.name, 'get', x, y)
3004 def put(self, data, to=None):
3005 """Put row formated colors to image starting from
3006 position TO, e.g. image.put("{red green} {blue yellow}", to=(4,6))"""
3007 args = (self.name, 'put', data)
3008 if to:
3009 if to[0] == '-to':
3010 to = to[1:]
3011 args = args + ('-to',) + tuple(to)
3012 self.tk.call(args)
3013 # XXX read
3014 def write(self, filename, format=None, from_coords=None):
3015 """Write image to file FILENAME in FORMAT starting from
3016 position FROM_COORDS."""
3017 args = (self.name, 'write', filename)
3018 if format:
3019 args = args + ('-format', format)
3020 if from_coords:
3021 args = args + ('-from',) + tuple(from_coords)
3022 self.tk.call(args)
Guido van Rossum35f67fb1995-08-04 03:50:29 +00003023
3024class BitmapImage(Image):
Fredrik Lundh06d28152000-08-09 18:03:12 +00003025 """Widget which can display a bitmap."""
3026 def __init__(self, name=None, cnf={}, master=None, **kw):
3027 """Create a bitmap with NAME.
Guido van Rossum5917ecb2000-06-29 16:30:50 +00003028
Fredrik Lundh06d28152000-08-09 18:03:12 +00003029 Valid resource names: background, data, file, foreground, maskdata, maskfile."""
3030 apply(Image.__init__, (self, 'bitmap', name, cnf, master), kw)
Guido van Rossum35f67fb1995-08-04 03:50:29 +00003031
3032def image_names(): return _default_root.tk.call('image', 'names')
3033def image_types(): return _default_root.tk.call('image', 'types')
3034
Guido van Rossumaec5dc91994-06-27 07:55:12 +00003035######################################################################
3036# Extensions:
3037
3038class Studbutton(Button):
Fredrik Lundh06d28152000-08-09 18:03:12 +00003039 def __init__(self, master=None, cnf={}, **kw):
3040 Widget.__init__(self, master, 'studbutton', cnf, kw)
3041 self.bind('<Any-Enter>', self.tkButtonEnter)
3042 self.bind('<Any-Leave>', self.tkButtonLeave)
3043 self.bind('<1>', self.tkButtonDown)
3044 self.bind('<ButtonRelease-1>', self.tkButtonUp)
Guido van Rossumaec5dc91994-06-27 07:55:12 +00003045
3046class Tributton(Button):
Fredrik Lundh06d28152000-08-09 18:03:12 +00003047 def __init__(self, master=None, cnf={}, **kw):
3048 Widget.__init__(self, master, 'tributton', cnf, kw)
3049 self.bind('<Any-Enter>', self.tkButtonEnter)
3050 self.bind('<Any-Leave>', self.tkButtonLeave)
3051 self.bind('<1>', self.tkButtonDown)
3052 self.bind('<ButtonRelease-1>', self.tkButtonUp)
3053 self['fg'] = self['bg']
3054 self['activebackground'] = self['bg']
Guido van Rossum37dcab11996-05-16 16:00:19 +00003055
Guido van Rossumc417ef81996-08-21 23:38:59 +00003056######################################################################
3057# Test:
3058
3059def _test():
Fredrik Lundh06d28152000-08-09 18:03:12 +00003060 root = Tk()
3061 text = "This is Tcl/Tk version %s" % TclVersion
3062 if TclVersion >= 8.1:
3063 text = text + u"\nThis should be a cedilla: \347"
3064 label = Label(root, text=text)
3065 label.pack()
3066 test = Button(root, text="Click me!",
3067 command=lambda root=root: root.test.configure(
3068 text="[%s]" % root.test['text']))
3069 test.pack()
3070 root.test = test
3071 quit = Button(root, text="QUIT", command=root.destroy)
3072 quit.pack()
3073 # The following three commands are needed so the window pops
3074 # up on top on Windows...
3075 root.iconify()
3076 root.update()
3077 root.deiconify()
3078 root.mainloop()
Guido van Rossumc417ef81996-08-21 23:38:59 +00003079
3080if __name__ == '__main__':
Fredrik Lundh06d28152000-08-09 18:03:12 +00003081 _test()
Guido van Rossum5917ecb2000-06-29 16:30:50 +00003082