Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | """Wrapper functions for Tcl/Tk. |
2 | ||
3 | Tkinter provides classes which allow the display, positioning and | |
4 | control of widgets. Toplevel widgets are Tk and Toplevel. Other | |
5 | widgets are Frame, Label, Entry, Text, Canvas, Button, Radiobutton, | |
6 | Checkbutton, Scale, Listbox, Scrollbar, OptionMenu, Spinbox | |
7 | LabelFrame and PanedWindow. | |
8 | ||
9 | Properties of the widgets are specified with keyword arguments. | |
10 | Keyword arguments have the same name as the corresponding resource | |
11 | under Tk. | |
12 | ||
13 | Widgets are positioned with one of the geometry managers Place, Pack | |
14 | or Grid. These managers can be called with methods place, pack, grid | |
15 | available in every Widget. | |
16 | ||
17 | Actions are bound to events by resources (e.g. keyword argument | |
18 | command) or with the method bind. | |
19 | ||
20 | Example (Hello, World): | |
21 | import Tkinter | |
22 | from Tkconstants import * | |
23 | tk = Tkinter.Tk() | |
24 | frame = Tkinter.Frame(tk, relief=RIDGE, borderwidth=2) | |
25 | frame.pack(fill=BOTH,expand=1) | |
26 | label = Tkinter.Label(frame, text="Hello, World") | |
27 | label.pack(fill=X, expand=1) | |
28 | button = Tkinter.Button(frame,text="Exit",command=tk.destroy) | |
29 | button.pack(side=BOTTOM) | |
30 | tk.mainloop() | |
31 | """ | |
32 | ||
33 | __version__ = "$Revision: 1.181.2.2 $" | |
34 | ||
35 | import sys | |
36 | if sys.platform == "win32": | |
37 | import FixTk # Attempt to configure Tcl/Tk without requiring PATH | |
38 | import _tkinter # If this fails your Python may not be configured for Tk | |
39 | tkinter = _tkinter # b/w compat for export | |
40 | TclError = _tkinter.TclError | |
41 | from types import * | |
42 | from Tkconstants import * | |
43 | try: | |
44 | import MacOS; _MacOS = MacOS; del MacOS | |
45 | except ImportError: | |
46 | _MacOS = None | |
47 | ||
48 | wantobjects = 1 | |
49 | ||
50 | TkVersion = float(_tkinter.TK_VERSION) | |
51 | TclVersion = float(_tkinter.TCL_VERSION) | |
52 | ||
53 | READABLE = _tkinter.READABLE | |
54 | WRITABLE = _tkinter.WRITABLE | |
55 | EXCEPTION = _tkinter.EXCEPTION | |
56 | ||
57 | # These are not always defined, e.g. not on Win32 with Tk 8.0 :-( | |
58 | try: _tkinter.createfilehandler | |
59 | except AttributeError: _tkinter.createfilehandler = None | |
60 | try: _tkinter.deletefilehandler | |
61 | except AttributeError: _tkinter.deletefilehandler = None | |
62 | ||
63 | ||
64 | def _flatten(tuple): | |
65 | """Internal function.""" | |
66 | res = () | |
67 | for item in tuple: | |
68 | if type(item) in (TupleType, ListType): | |
69 | res = res + _flatten(item) | |
70 | elif item is not None: | |
71 | res = res + (item,) | |
72 | return res | |
73 | ||
74 | try: _flatten = _tkinter._flatten | |
75 | except AttributeError: pass | |
76 | ||
77 | def _cnfmerge(cnfs): | |
78 | """Internal function.""" | |
79 | if type(cnfs) is DictionaryType: | |
80 | return cnfs | |
81 | elif type(cnfs) in (NoneType, StringType): | |
82 | return cnfs | |
83 | else: | |
84 | cnf = {} | |
85 | for c in _flatten(cnfs): | |
86 | try: | |
87 | cnf.update(c) | |
88 | except (AttributeError, TypeError), msg: | |
89 | print "_cnfmerge: fallback due to:", msg | |
90 | for k, v in c.items(): | |
91 | cnf[k] = v | |
92 | return cnf | |
93 | ||
94 | try: _cnfmerge = _tkinter._cnfmerge | |
95 | except AttributeError: pass | |
96 | ||
97 | class Event: | |
98 | """Container for the properties of an event. | |
99 | ||
100 | Instances of this type are generated if one of the following events occurs: | |
101 | ||
102 | KeyPress, KeyRelease - for keyboard events | |
103 | ButtonPress, ButtonRelease, Motion, Enter, Leave, MouseWheel - for mouse events | |
104 | Visibility, Unmap, Map, Expose, FocusIn, FocusOut, Circulate, | |
105 | Colormap, Gravity, Reparent, Property, Destroy, Activate, | |
106 | Deactivate - for window events. | |
107 | ||
108 | If a callback function for one of these events is registered | |
109 | using bind, bind_all, bind_class, or tag_bind, the callback is | |
110 | called with an Event as first argument. It will have the | |
111 | following attributes (in braces are the event types for which | |
112 | the attribute is valid): | |
113 | ||
114 | serial - serial number of event | |
115 | num - mouse button pressed (ButtonPress, ButtonRelease) | |
116 | focus - whether the window has the focus (Enter, Leave) | |
117 | height - height of the exposed window (Configure, Expose) | |
118 | width - width of the exposed window (Configure, Expose) | |
119 | keycode - keycode of the pressed key (KeyPress, KeyRelease) | |
120 | state - state of the event as a number (ButtonPress, ButtonRelease, | |
121 | Enter, KeyPress, KeyRelease, | |
122 | Leave, Motion) | |
123 | state - state as a string (Visibility) | |
124 | time - when the event occurred | |
125 | x - x-position of the mouse | |
126 | y - y-position of the mouse | |
127 | x_root - x-position of the mouse on the screen | |
128 | (ButtonPress, ButtonRelease, KeyPress, KeyRelease, Motion) | |
129 | y_root - y-position of the mouse on the screen | |
130 | (ButtonPress, ButtonRelease, KeyPress, KeyRelease, Motion) | |
131 | char - pressed character (KeyPress, KeyRelease) | |
132 | send_event - see X/Windows documentation | |
133 | keysym - keysym of the the event as a string (KeyPress, KeyRelease) | |
134 | keysym_num - keysym of the event as a number (KeyPress, KeyRelease) | |
135 | type - type of the event as a number | |
136 | widget - widget in which the event occurred | |
137 | delta - delta of wheel movement (MouseWheel) | |
138 | """ | |
139 | pass | |
140 | ||
141 | _support_default_root = 1 | |
142 | _default_root = None | |
143 | ||
144 | def NoDefaultRoot(): | |
145 | """Inhibit setting of default root window. | |
146 | ||
147 | Call this function to inhibit that the first instance of | |
148 | Tk is used for windows without an explicit parent window. | |
149 | """ | |
150 | global _support_default_root | |
151 | _support_default_root = 0 | |
152 | global _default_root | |
153 | _default_root = None | |
154 | del _default_root | |
155 | ||
156 | def _tkerror(err): | |
157 | """Internal function.""" | |
158 | pass | |
159 | ||
160 | def _exit(code='0'): | |
161 | """Internal function. Calling it will throw the exception SystemExit.""" | |
162 | raise SystemExit, code | |
163 | ||
164 | _varnum = 0 | |
165 | class Variable: | |
166 | """Class to define value holders for e.g. buttons. | |
167 | ||
168 | Subclasses StringVar, IntVar, DoubleVar, BooleanVar are specializations | |
169 | that constrain the type of the value returned from get().""" | |
170 | _default = "" | |
171 | def __init__(self, master=None): | |
172 | """Construct a variable with an optional MASTER as master widget. | |
173 | The variable is named PY_VAR_number in Tcl. | |
174 | """ | |
175 | global _varnum | |
176 | if not master: | |
177 | master = _default_root | |
178 | self._master = master | |
179 | self._tk = master.tk | |
180 | self._name = 'PY_VAR' + repr(_varnum) | |
181 | _varnum = _varnum + 1 | |
182 | self.set(self._default) | |
183 | def __del__(self): | |
184 | """Unset the variable in Tcl.""" | |
185 | self._tk.globalunsetvar(self._name) | |
186 | def __str__(self): | |
187 | """Return the name of the variable in Tcl.""" | |
188 | return self._name | |
189 | def set(self, value): | |
190 | """Set the variable to VALUE.""" | |
191 | return self._tk.globalsetvar(self._name, value) | |
192 | def get(self): | |
193 | """Return value of variable.""" | |
194 | return self._tk.globalgetvar(self._name) | |
195 | def trace_variable(self, mode, callback): | |
196 | """Define a trace callback for the variable. | |
197 | ||
198 | MODE is one of "r", "w", "u" for read, write, undefine. | |
199 | CALLBACK must be a function which is called when | |
200 | the variable is read, written or undefined. | |
201 | ||
202 | Return the name of the callback. | |
203 | """ | |
204 | cbname = self._master._register(callback) | |
205 | self._tk.call("trace", "variable", self._name, mode, cbname) | |
206 | return cbname | |
207 | trace = trace_variable | |
208 | def trace_vdelete(self, mode, cbname): | |
209 | """Delete the trace callback for a variable. | |
210 | ||
211 | MODE is one of "r", "w", "u" for read, write, undefine. | |
212 | CBNAME is the name of the callback returned from trace_variable or trace. | |
213 | """ | |
214 | self._tk.call("trace", "vdelete", self._name, mode, cbname) | |
215 | self._master.deletecommand(cbname) | |
216 | def trace_vinfo(self): | |
217 | """Return all trace callback information.""" | |
218 | return map(self._tk.split, self._tk.splitlist( | |
219 | self._tk.call("trace", "vinfo", self._name))) | |
220 | ||
221 | class StringVar(Variable): | |
222 | """Value holder for strings variables.""" | |
223 | _default = "" | |
224 | def __init__(self, master=None): | |
225 | """Construct a string variable. | |
226 | ||
227 | MASTER can be given as master widget.""" | |
228 | Variable.__init__(self, master) | |
229 | ||
230 | def get(self): | |
231 | """Return value of variable as string.""" | |
232 | value = self._tk.globalgetvar(self._name) | |
233 | if isinstance(value, basestring): | |
234 | return value | |
235 | return str(value) | |
236 | ||
237 | class IntVar(Variable): | |
238 | """Value holder for integer variables.""" | |
239 | _default = 0 | |
240 | def __init__(self, master=None): | |
241 | """Construct an integer variable. | |
242 | ||
243 | MASTER can be given as master widget.""" | |
244 | Variable.__init__(self, master) | |
245 | ||
246 | def set(self, value): | |
247 | """Set the variable to value, converting booleans to integers.""" | |
248 | if isinstance(value, bool): | |
249 | value = int(value) | |
250 | return Variable.set(self, value) | |
251 | ||
252 | def get(self): | |
253 | """Return the value of the variable as an integer.""" | |
254 | return getint(self._tk.globalgetvar(self._name)) | |
255 | ||
256 | class DoubleVar(Variable): | |
257 | """Value holder for float variables.""" | |
258 | _default = 0.0 | |
259 | def __init__(self, master=None): | |
260 | """Construct a float variable. | |
261 | ||
262 | MASTER can be given as a master widget.""" | |
263 | Variable.__init__(self, master) | |
264 | ||
265 | def get(self): | |
266 | """Return the value of the variable as a float.""" | |
267 | return getdouble(self._tk.globalgetvar(self._name)) | |
268 | ||
269 | class BooleanVar(Variable): | |
270 | """Value holder for boolean variables.""" | |
271 | _default = "false" | |
272 | def __init__(self, master=None): | |
273 | """Construct a boolean variable. | |
274 | ||
275 | MASTER can be given as a master widget.""" | |
276 | Variable.__init__(self, master) | |
277 | ||
278 | def get(self): | |
279 | """Return the value of the variable as a bool.""" | |
280 | return self._tk.getboolean(self._tk.globalgetvar(self._name)) | |
281 | ||
282 | def mainloop(n=0): | |
283 | """Run the main loop of Tcl.""" | |
284 | _default_root.tk.mainloop(n) | |
285 | ||
286 | getint = int | |
287 | ||
288 | getdouble = float | |
289 | ||
290 | def getboolean(s): | |
291 | """Convert true and false to integer values 1 and 0.""" | |
292 | return _default_root.tk.getboolean(s) | |
293 | ||
294 | # Methods defined on both toplevel and interior widgets | |
295 | class Misc: | |
296 | """Internal class. | |
297 | ||
298 | Base class which defines methods common for interior widgets.""" | |
299 | ||
300 | # XXX font command? | |
301 | _tclCommands = None | |
302 | def destroy(self): | |
303 | """Internal function. | |
304 | ||
305 | Delete all Tcl commands created for | |
306 | this widget in the Tcl interpreter.""" | |
307 | if self._tclCommands is not None: | |
308 | for name in self._tclCommands: | |
309 | #print '- Tkinter: deleted command', name | |
310 | self.tk.deletecommand(name) | |
311 | self._tclCommands = None | |
312 | def deletecommand(self, name): | |
313 | """Internal function. | |
314 | ||
315 | Delete the Tcl command provided in NAME.""" | |
316 | #print '- Tkinter: deleted command', name | |
317 | self.tk.deletecommand(name) | |
318 | try: | |
319 | self._tclCommands.remove(name) | |
320 | except ValueError: | |
321 | pass | |
322 | def tk_strictMotif(self, boolean=None): | |
323 | """Set Tcl internal variable, whether the look and feel | |
324 | should adhere to Motif. | |
325 | ||
326 | A parameter of 1 means adhere to Motif (e.g. no color | |
327 | change if mouse passes over slider). | |
328 | Returns the set value.""" | |
329 | return self.tk.getboolean(self.tk.call( | |
330 | 'set', 'tk_strictMotif', boolean)) | |
331 | def tk_bisque(self): | |
332 | """Change the color scheme to light brown as used in Tk 3.6 and before.""" | |
333 | self.tk.call('tk_bisque') | |
334 | def tk_setPalette(self, *args, **kw): | |
335 | """Set a new color scheme for all widget elements. | |
336 | ||
337 | A single color as argument will cause that all colors of Tk | |
338 | widget elements are derived from this. | |
339 | Alternatively several keyword parameters and its associated | |
340 | colors can be given. The following keywords are valid: | |
341 | activeBackground, foreground, selectColor, | |
342 | activeForeground, highlightBackground, selectBackground, | |
343 | background, highlightColor, selectForeground, | |
344 | disabledForeground, insertBackground, troughColor.""" | |
345 | self.tk.call(('tk_setPalette',) | |
346 | + _flatten(args) + _flatten(kw.items())) | |
347 | def tk_menuBar(self, *args): | |
348 | """Do not use. Needed in Tk 3.6 and earlier.""" | |
349 | pass # obsolete since Tk 4.0 | |
350 | def wait_variable(self, name='PY_VAR'): | |
351 | """Wait until the variable is modified. | |
352 | ||
353 | A parameter of type IntVar, StringVar, DoubleVar or | |
354 | BooleanVar must be given.""" | |
355 | self.tk.call('tkwait', 'variable', name) | |
356 | waitvar = wait_variable # XXX b/w compat | |
357 | def wait_window(self, window=None): | |
358 | """Wait until a WIDGET is destroyed. | |
359 | ||
360 | If no parameter is given self is used.""" | |
361 | if window is None: | |
362 | window = self | |
363 | self.tk.call('tkwait', 'window', window._w) | |
364 | def wait_visibility(self, window=None): | |
365 | """Wait until the visibility of a WIDGET changes | |
366 | (e.g. it appears). | |
367 | ||
368 | If no parameter is given self is used.""" | |
369 | if window is None: | |
370 | window = self | |
371 | self.tk.call('tkwait', 'visibility', window._w) | |
372 | def setvar(self, name='PY_VAR', value='1'): | |
373 | """Set Tcl variable NAME to VALUE.""" | |
374 | self.tk.setvar(name, value) | |
375 | def getvar(self, name='PY_VAR'): | |
376 | """Return value of Tcl variable NAME.""" | |
377 | return self.tk.getvar(name) | |
378 | getint = int | |
379 | getdouble = float | |
380 | def getboolean(self, s): | |
381 | """Return a boolean value for Tcl boolean values true and false given as parameter.""" | |
382 | return self.tk.getboolean(s) | |
383 | def focus_set(self): | |
384 | """Direct input focus to this widget. | |
385 | ||
386 | If the application currently does not have the focus | |
387 | this widget will get the focus if the application gets | |
388 | the focus through the window manager.""" | |
389 | self.tk.call('focus', self._w) | |
390 | focus = focus_set # XXX b/w compat? | |
391 | def focus_force(self): | |
392 | """Direct input focus to this widget even if the | |
393 | application does not have the focus. Use with | |
394 | caution!""" | |
395 | self.tk.call('focus', '-force', self._w) | |
396 | def focus_get(self): | |
397 | """Return the widget which has currently the focus in the | |
398 | application. | |
399 | ||
400 | Use focus_displayof to allow working with several | |
401 | displays. Return None if application does not have | |
402 | the focus.""" | |
403 | name = self.tk.call('focus') | |
404 | if name == 'none' or not name: return None | |
405 | return self._nametowidget(name) | |
406 | def focus_displayof(self): | |
407 | """Return the widget which has currently the focus on the | |
408 | display where this widget is located. | |
409 | ||
410 | Return None if the application does not have the focus.""" | |
411 | name = self.tk.call('focus', '-displayof', self._w) | |
412 | if name == 'none' or not name: return None | |
413 | return self._nametowidget(name) | |
414 | def focus_lastfor(self): | |
415 | """Return the widget which would have the focus if top level | |
416 | for this widget gets the focus from the window manager.""" | |
417 | name = self.tk.call('focus', '-lastfor', self._w) | |
418 | if name == 'none' or not name: return None | |
419 | return self._nametowidget(name) | |
420 | def tk_focusFollowsMouse(self): | |
421 | """The widget under mouse will get automatically focus. Can not | |
422 | be disabled easily.""" | |
423 | self.tk.call('tk_focusFollowsMouse') | |
424 | def tk_focusNext(self): | |
425 | """Return the next widget in the focus order which follows | |
426 | widget which has currently the focus. | |
427 | ||
428 | The focus order first goes to the next child, then to | |
429 | the children of the child recursively and then to the | |
430 | next sibling which is higher in the stacking order. A | |
431 | widget is omitted if it has the takefocus resource set | |
432 | to 0.""" | |
433 | name = self.tk.call('tk_focusNext', self._w) | |
434 | if not name: return None | |
435 | return self._nametowidget(name) | |
436 | def tk_focusPrev(self): | |
437 | """Return previous widget in the focus order. See tk_focusNext for details.""" | |
438 | name = self.tk.call('tk_focusPrev', self._w) | |
439 | if not name: return None | |
440 | return self._nametowidget(name) | |
441 | def after(self, ms, func=None, *args): | |
442 | """Call function once after given time. | |
443 | ||
444 | MS specifies the time in milliseconds. FUNC gives the | |
445 | function which shall be called. Additional parameters | |
446 | are given as parameters to the function call. Return | |
447 | identifier to cancel scheduling with after_cancel.""" | |
448 | if not func: | |
449 | # I'd rather use time.sleep(ms*0.001) | |
450 | self.tk.call('after', ms) | |
451 | else: | |
452 | # XXX Disgusting hack to clean up after calling func | |
453 | tmp = [] | |
454 | def callit(func=func, args=args, self=self, tmp=tmp): | |
455 | try: | |
456 | func(*args) | |
457 | finally: | |
458 | try: | |
459 | self.deletecommand(tmp[0]) | |
460 | except TclError: | |
461 | pass | |
462 | name = self._register(callit) | |
463 | tmp.append(name) | |
464 | return self.tk.call('after', ms, name) | |
465 | def after_idle(self, func, *args): | |
466 | """Call FUNC once if the Tcl main loop has no event to | |
467 | process. | |
468 | ||
469 | Return an identifier to cancel the scheduling with | |
470 | after_cancel.""" | |
471 | return self.after('idle', func, *args) | |
472 | def after_cancel(self, id): | |
473 | """Cancel scheduling of function identified with ID. | |
474 | ||
475 | Identifier returned by after or after_idle must be | |
476 | given as first parameter.""" | |
477 | try: | |
478 | data = self.tk.call('after', 'info', id) | |
479 | # In Tk 8.3, splitlist returns: (script, type) | |
480 | # In Tk 8.4, splitlist may return (script, type) or (script,) | |
481 | script = self.tk.splitlist(data)[0] | |
482 | self.deletecommand(script) | |
483 | except TclError: | |
484 | pass | |
485 | self.tk.call('after', 'cancel', id) | |
486 | def bell(self, displayof=0): | |
487 | """Ring a display's bell.""" | |
488 | self.tk.call(('bell',) + self._displayof(displayof)) | |
489 | # Clipboard handling: | |
490 | def clipboard_clear(self, **kw): | |
491 | """Clear the data in the Tk clipboard. | |
492 | ||
493 | A widget specified for the optional displayof keyword | |
494 | argument specifies the target display.""" | |
495 | if not kw.has_key('displayof'): kw['displayof'] = self._w | |
496 | self.tk.call(('clipboard', 'clear') + self._options(kw)) | |
497 | def clipboard_append(self, string, **kw): | |
498 | """Append STRING to the Tk clipboard. | |
499 | ||
500 | A widget specified at the optional displayof keyword | |
501 | argument specifies the target display. The clipboard | |
502 | can be retrieved with selection_get.""" | |
503 | if not kw.has_key('displayof'): kw['displayof'] = self._w | |
504 | self.tk.call(('clipboard', 'append') + self._options(kw) | |
505 | + ('--', string)) | |
506 | # XXX grab current w/o window argument | |
507 | def grab_current(self): | |
508 | """Return widget which has currently the grab in this application | |
509 | or None.""" | |
510 | name = self.tk.call('grab', 'current', self._w) | |
511 | if not name: return None | |
512 | return self._nametowidget(name) | |
513 | def grab_release(self): | |
514 | """Release grab for this widget if currently set.""" | |
515 | self.tk.call('grab', 'release', self._w) | |
516 | def grab_set(self): | |
517 | """Set grab for this widget. | |
518 | ||
519 | A grab directs all events to this and descendant | |
520 | widgets in the application.""" | |
521 | self.tk.call('grab', 'set', self._w) | |
522 | def grab_set_global(self): | |
523 | """Set global grab for this widget. | |
524 | ||
525 | A global grab directs all events to this and | |
526 | descendant widgets on the display. Use with caution - | |
527 | other applications do not get events anymore.""" | |
528 | self.tk.call('grab', 'set', '-global', self._w) | |
529 | def grab_status(self): | |
530 | """Return None, "local" or "global" if this widget has | |
531 | no, a local or a global grab.""" | |
532 | status = self.tk.call('grab', 'status', self._w) | |
533 | if status == 'none': status = None | |
534 | return status | |
535 | def lower(self, belowThis=None): | |
536 | """Lower this widget in the stacking order.""" | |
537 | self.tk.call('lower', self._w, belowThis) | |
538 | def option_add(self, pattern, value, priority = None): | |
539 | """Set a VALUE (second parameter) for an option | |
540 | PATTERN (first parameter). | |
541 | ||
542 | An optional third parameter gives the numeric priority | |
543 | (defaults to 80).""" | |
544 | self.tk.call('option', 'add', pattern, value, priority) | |
545 | def option_clear(self): | |
546 | """Clear the option database. | |
547 | ||
548 | It will be reloaded if option_add is called.""" | |
549 | self.tk.call('option', 'clear') | |
550 | def option_get(self, name, className): | |
551 | """Return the value for an option NAME for this widget | |
552 | with CLASSNAME. | |
553 | ||
554 | Values with higher priority override lower values.""" | |
555 | return self.tk.call('option', 'get', self._w, name, className) | |
556 | def option_readfile(self, fileName, priority = None): | |
557 | """Read file FILENAME into the option database. | |
558 | ||
559 | An optional second parameter gives the numeric | |
560 | priority.""" | |
561 | self.tk.call('option', 'readfile', fileName, priority) | |
562 | def selection_clear(self, **kw): | |
563 | """Clear the current X selection.""" | |
564 | if not kw.has_key('displayof'): kw['displayof'] = self._w | |
565 | self.tk.call(('selection', 'clear') + self._options(kw)) | |
566 | def selection_get(self, **kw): | |
567 | """Return the contents of the current X selection. | |
568 | ||
569 | A keyword parameter selection specifies the name of | |
570 | the selection and defaults to PRIMARY. A keyword | |
571 | parameter displayof specifies a widget on the display | |
572 | to use.""" | |
573 | if not kw.has_key('displayof'): kw['displayof'] = self._w | |
574 | return self.tk.call(('selection', 'get') + self._options(kw)) | |
575 | def selection_handle(self, command, **kw): | |
576 | """Specify a function COMMAND to call if the X | |
577 | selection owned by this widget is queried by another | |
578 | application. | |
579 | ||
580 | This function must return the contents of the | |
581 | selection. The function will be called with the | |
582 | arguments OFFSET and LENGTH which allows the chunking | |
583 | of very long selections. The following keyword | |
584 | parameters can be provided: | |
585 | selection - name of the selection (default PRIMARY), | |
586 | type - type of the selection (e.g. STRING, FILE_NAME).""" | |
587 | name = self._register(command) | |
588 | self.tk.call(('selection', 'handle') + self._options(kw) | |
589 | + (self._w, name)) | |
590 | def selection_own(self, **kw): | |
591 | """Become owner of X selection. | |
592 | ||
593 | A keyword parameter selection specifies the name of | |
594 | the selection (default PRIMARY).""" | |
595 | self.tk.call(('selection', 'own') + | |
596 | self._options(kw) + (self._w,)) | |
597 | def selection_own_get(self, **kw): | |
598 | """Return owner of X selection. | |
599 | ||
600 | The following keyword parameter can | |
601 | be provided: | |
602 | selection - name of the selection (default PRIMARY), | |
603 | type - type of the selection (e.g. STRING, FILE_NAME).""" | |
604 | if not kw.has_key('displayof'): kw['displayof'] = self._w | |
605 | name = self.tk.call(('selection', 'own') + self._options(kw)) | |
606 | if not name: return None | |
607 | return self._nametowidget(name) | |
608 | def send(self, interp, cmd, *args): | |
609 | """Send Tcl command CMD to different interpreter INTERP to be executed.""" | |
610 | return self.tk.call(('send', interp, cmd) + args) | |
611 | def lower(self, belowThis=None): | |
612 | """Lower this widget in the stacking order.""" | |
613 | self.tk.call('lower', self._w, belowThis) | |
614 | def tkraise(self, aboveThis=None): | |
615 | """Raise this widget in the stacking order.""" | |
616 | self.tk.call('raise', self._w, aboveThis) | |
617 | lift = tkraise | |
618 | def colormodel(self, value=None): | |
619 | """Useless. Not implemented in Tk.""" | |
620 | return self.tk.call('tk', 'colormodel', self._w, value) | |
621 | def winfo_atom(self, name, displayof=0): | |
622 | """Return integer which represents atom NAME.""" | |
623 | args = ('winfo', 'atom') + self._displayof(displayof) + (name,) | |
624 | return getint(self.tk.call(args)) | |
625 | def winfo_atomname(self, id, displayof=0): | |
626 | """Return name of atom with identifier ID.""" | |
627 | args = ('winfo', 'atomname') \ | |
628 | + self._displayof(displayof) + (id,) | |
629 | return self.tk.call(args) | |
630 | def winfo_cells(self): | |
631 | """Return number of cells in the colormap for this widget.""" | |
632 | return getint( | |
633 | self.tk.call('winfo', 'cells', self._w)) | |
634 | def winfo_children(self): | |
635 | """Return a list of all widgets which are children of this widget.""" | |
636 | result = [] | |
637 | for child in self.tk.splitlist( | |
638 | self.tk.call('winfo', 'children', self._w)): | |
639 | try: | |
640 | # Tcl sometimes returns extra windows, e.g. for | |
641 | # menus; those need to be skipped | |
642 | result.append(self._nametowidget(child)) | |
643 | except KeyError: | |
644 | pass | |
645 | return result | |
646 | ||
647 | def winfo_class(self): | |
648 | """Return window class name of this widget.""" | |
649 | return self.tk.call('winfo', 'class', self._w) | |
650 | def winfo_colormapfull(self): | |
651 | """Return true if at the last color request the colormap was full.""" | |
652 | return self.tk.getboolean( | |
653 | self.tk.call('winfo', 'colormapfull', self._w)) | |
654 | def winfo_containing(self, rootX, rootY, displayof=0): | |
655 | """Return the widget which is at the root coordinates ROOTX, ROOTY.""" | |
656 | args = ('winfo', 'containing') \ | |
657 | + self._displayof(displayof) + (rootX, rootY) | |
658 | name = self.tk.call(args) | |
659 | if not name: return None | |
660 | return self._nametowidget(name) | |
661 | def winfo_depth(self): | |
662 | """Return the number of bits per pixel.""" | |
663 | return getint(self.tk.call('winfo', 'depth', self._w)) | |
664 | def winfo_exists(self): | |
665 | """Return true if this widget exists.""" | |
666 | return getint( | |
667 | self.tk.call('winfo', 'exists', self._w)) | |
668 | def winfo_fpixels(self, number): | |
669 | """Return the number of pixels for the given distance NUMBER | |
670 | (e.g. "3c") as float.""" | |
671 | return getdouble(self.tk.call( | |
672 | 'winfo', 'fpixels', self._w, number)) | |
673 | def winfo_geometry(self): | |
674 | """Return geometry string for this widget in the form "widthxheight+X+Y".""" | |
675 | return self.tk.call('winfo', 'geometry', self._w) | |
676 | def winfo_height(self): | |
677 | """Return height of this widget.""" | |
678 | return getint( | |
679 | self.tk.call('winfo', 'height', self._w)) | |
680 | def winfo_id(self): | |
681 | """Return identifier ID for this widget.""" | |
682 | return self.tk.getint( | |
683 | self.tk.call('winfo', 'id', self._w)) | |
684 | def winfo_interps(self, displayof=0): | |
685 | """Return the name of all Tcl interpreters for this display.""" | |
686 | args = ('winfo', 'interps') + self._displayof(displayof) | |
687 | return self.tk.splitlist(self.tk.call(args)) | |
688 | def winfo_ismapped(self): | |
689 | """Return true if this widget is mapped.""" | |
690 | return getint( | |
691 | self.tk.call('winfo', 'ismapped', self._w)) | |
692 | def winfo_manager(self): | |
693 | """Return the window mananger name for this widget.""" | |
694 | return self.tk.call('winfo', 'manager', self._w) | |
695 | def winfo_name(self): | |
696 | """Return the name of this widget.""" | |
697 | return self.tk.call('winfo', 'name', self._w) | |
698 | def winfo_parent(self): | |
699 | """Return the name of the parent of this widget.""" | |
700 | return self.tk.call('winfo', 'parent', self._w) | |
701 | def winfo_pathname(self, id, displayof=0): | |
702 | """Return the pathname of the widget given by ID.""" | |
703 | args = ('winfo', 'pathname') \ | |
704 | + self._displayof(displayof) + (id,) | |
705 | return self.tk.call(args) | |
706 | def winfo_pixels(self, number): | |
707 | """Rounded integer value of winfo_fpixels.""" | |
708 | return getint( | |
709 | self.tk.call('winfo', 'pixels', self._w, number)) | |
710 | def winfo_pointerx(self): | |
711 | """Return the x coordinate of the pointer on the root window.""" | |
712 | return getint( | |
713 | self.tk.call('winfo', 'pointerx', self._w)) | |
714 | def winfo_pointerxy(self): | |
715 | """Return a tuple of x and y coordinates of the pointer on the root window.""" | |
716 | return self._getints( | |
717 | self.tk.call('winfo', 'pointerxy', self._w)) | |
718 | def winfo_pointery(self): | |
719 | """Return the y coordinate of the pointer on the root window.""" | |
720 | return getint( | |
721 | self.tk.call('winfo', 'pointery', self._w)) | |
722 | def winfo_reqheight(self): | |
723 | """Return requested height of this widget.""" | |
724 | return getint( | |
725 | self.tk.call('winfo', 'reqheight', self._w)) | |
726 | def winfo_reqwidth(self): | |
727 | """Return requested width of this widget.""" | |
728 | return getint( | |
729 | self.tk.call('winfo', 'reqwidth', self._w)) | |
730 | def winfo_rgb(self, color): | |
731 | """Return tuple of decimal values for red, green, blue for | |
732 | COLOR in this widget.""" | |
733 | return self._getints( | |
734 | self.tk.call('winfo', 'rgb', self._w, color)) | |
735 | def winfo_rootx(self): | |
736 | """Return x coordinate of upper left corner of this widget on the | |
737 | root window.""" | |
738 | return getint( | |
739 | self.tk.call('winfo', 'rootx', self._w)) | |
740 | def winfo_rooty(self): | |
741 | """Return y coordinate of upper left corner of this widget on the | |
742 | root window.""" | |
743 | return getint( | |
744 | self.tk.call('winfo', 'rooty', self._w)) | |
745 | def winfo_screen(self): | |
746 | """Return the screen name of this widget.""" | |
747 | return self.tk.call('winfo', 'screen', self._w) | |
748 | def winfo_screencells(self): | |
749 | """Return the number of the cells in the colormap of the screen | |
750 | of this widget.""" | |
751 | return getint( | |
752 | self.tk.call('winfo', 'screencells', self._w)) | |
753 | def winfo_screendepth(self): | |
754 | """Return the number of bits per pixel of the root window of the | |
755 | screen of this widget.""" | |
756 | return getint( | |
757 | self.tk.call('winfo', 'screendepth', self._w)) | |
758 | def winfo_screenheight(self): | |
759 | """Return the number of pixels of the height of the screen of this widget | |
760 | in pixel.""" | |
761 | return getint( | |
762 | self.tk.call('winfo', 'screenheight', self._w)) | |
763 | def winfo_screenmmheight(self): | |
764 | """Return the number of pixels of the height of the screen of | |
765 | this widget in mm.""" | |
766 | return getint( | |
767 | self.tk.call('winfo', 'screenmmheight', self._w)) | |
768 | def winfo_screenmmwidth(self): | |
769 | """Return the number of pixels of the width of the screen of | |
770 | this widget in mm.""" | |
771 | return getint( | |
772 | self.tk.call('winfo', 'screenmmwidth', self._w)) | |
773 | def winfo_screenvisual(self): | |
774 | """Return one of the strings directcolor, grayscale, pseudocolor, | |
775 | staticcolor, staticgray, or truecolor for the default | |
776 | colormodel of this screen.""" | |
777 | return self.tk.call('winfo', 'screenvisual', self._w) | |
778 | def winfo_screenwidth(self): | |
779 | """Return the number of pixels of the width of the screen of | |
780 | this widget in pixel.""" | |
781 | return getint( | |
782 | self.tk.call('winfo', 'screenwidth', self._w)) | |
783 | def winfo_server(self): | |
784 | """Return information of the X-Server of the screen of this widget in | |
785 | the form "XmajorRminor vendor vendorVersion".""" | |
786 | return self.tk.call('winfo', 'server', self._w) | |
787 | def winfo_toplevel(self): | |
788 | """Return the toplevel widget of this widget.""" | |
789 | return self._nametowidget(self.tk.call( | |
790 | 'winfo', 'toplevel', self._w)) | |
791 | def winfo_viewable(self): | |
792 | """Return true if the widget and all its higher ancestors are mapped.""" | |
793 | return getint( | |
794 | self.tk.call('winfo', 'viewable', self._w)) | |
795 | def winfo_visual(self): | |
796 | """Return one of the strings directcolor, grayscale, pseudocolor, | |
797 | staticcolor, staticgray, or truecolor for the | |
798 | colormodel of this widget.""" | |
799 | return self.tk.call('winfo', 'visual', self._w) | |
800 | def winfo_visualid(self): | |
801 | """Return the X identifier for the visual for this widget.""" | |
802 | return self.tk.call('winfo', 'visualid', self._w) | |
803 | def winfo_visualsavailable(self, includeids=0): | |
804 | """Return a list of all visuals available for the screen | |
805 | of this widget. | |
806 | ||
807 | Each item in the list consists of a visual name (see winfo_visual), a | |
808 | depth and if INCLUDEIDS=1 is given also the X identifier.""" | |
809 | data = self.tk.split( | |
810 | self.tk.call('winfo', 'visualsavailable', self._w, | |
811 | includeids and 'includeids' or None)) | |
812 | if type(data) is StringType: | |
813 | data = [self.tk.split(data)] | |
814 | return map(self.__winfo_parseitem, data) | |
815 | def __winfo_parseitem(self, t): | |
816 | """Internal function.""" | |
817 | return t[:1] + tuple(map(self.__winfo_getint, t[1:])) | |
818 | def __winfo_getint(self, x): | |
819 | """Internal function.""" | |
820 | return int(x, 0) | |
821 | def winfo_vrootheight(self): | |
822 | """Return the height of the virtual root window associated with this | |
823 | widget in pixels. If there is no virtual root window return the | |
824 | height of the screen.""" | |
825 | return getint( | |
826 | self.tk.call('winfo', 'vrootheight', self._w)) | |
827 | def winfo_vrootwidth(self): | |
828 | """Return the width of the virtual root window associated with this | |
829 | widget in pixel. If there is no virtual root window return the | |
830 | width of the screen.""" | |
831 | return getint( | |
832 | self.tk.call('winfo', 'vrootwidth', self._w)) | |
833 | def winfo_vrootx(self): | |
834 | """Return the x offset of the virtual root relative to the root | |
835 | window of the screen of this widget.""" | |
836 | return getint( | |
837 | self.tk.call('winfo', 'vrootx', self._w)) | |
838 | def winfo_vrooty(self): | |
839 | """Return the y offset of the virtual root relative to the root | |
840 | window of the screen of this widget.""" | |
841 | return getint( | |
842 | self.tk.call('winfo', 'vrooty', self._w)) | |
843 | def winfo_width(self): | |
844 | """Return the width of this widget.""" | |
845 | return getint( | |
846 | self.tk.call('winfo', 'width', self._w)) | |
847 | def winfo_x(self): | |
848 | """Return the x coordinate of the upper left corner of this widget | |
849 | in the parent.""" | |
850 | return getint( | |
851 | self.tk.call('winfo', 'x', self._w)) | |
852 | def winfo_y(self): | |
853 | """Return the y coordinate of the upper left corner of this widget | |
854 | in the parent.""" | |
855 | return getint( | |
856 | self.tk.call('winfo', 'y', self._w)) | |
857 | def update(self): | |
858 | """Enter event loop until all pending events have been processed by Tcl.""" | |
859 | self.tk.call('update') | |
860 | def update_idletasks(self): | |
861 | """Enter event loop until all idle callbacks have been called. This | |
862 | will update the display of windows but not process events caused by | |
863 | the user.""" | |
864 | self.tk.call('update', 'idletasks') | |
865 | def bindtags(self, tagList=None): | |
866 | """Set or get the list of bindtags for this widget. | |
867 | ||
868 | With no argument return the list of all bindtags associated with | |
869 | this widget. With a list of strings as argument the bindtags are | |
870 | set to this list. The bindtags determine in which order events are | |
871 | processed (see bind).""" | |
872 | if tagList is None: | |
873 | return self.tk.splitlist( | |
874 | self.tk.call('bindtags', self._w)) | |
875 | else: | |
876 | self.tk.call('bindtags', self._w, tagList) | |
877 | def _bind(self, what, sequence, func, add, needcleanup=1): | |
878 | """Internal function.""" | |
879 | if type(func) is StringType: | |
880 | self.tk.call(what + (sequence, func)) | |
881 | elif func: | |
882 | funcid = self._register(func, self._substitute, | |
883 | needcleanup) | |
884 | cmd = ('%sif {"[%s %s]" == "break"} break\n' | |
885 | % | |
886 | (add and '+' or '', | |
887 | funcid, self._subst_format_str)) | |
888 | self.tk.call(what + (sequence, cmd)) | |
889 | return funcid | |
890 | elif sequence: | |
891 | return self.tk.call(what + (sequence,)) | |
892 | else: | |
893 | return self.tk.splitlist(self.tk.call(what)) | |
894 | def bind(self, sequence=None, func=None, add=None): | |
895 | """Bind to this widget at event SEQUENCE a call to function FUNC. | |
896 | ||
897 | SEQUENCE is a string of concatenated event | |
898 | patterns. An event pattern is of the form | |
899 | <MODIFIER-MODIFIER-TYPE-DETAIL> where MODIFIER is one | |
900 | of Control, Mod2, M2, Shift, Mod3, M3, Lock, Mod4, M4, | |
901 | Button1, B1, Mod5, M5 Button2, B2, Meta, M, Button3, | |
902 | B3, Alt, Button4, B4, Double, Button5, B5 Triple, | |
903 | Mod1, M1. TYPE is one of Activate, Enter, Map, | |
904 | ButtonPress, Button, Expose, Motion, ButtonRelease | |
905 | FocusIn, MouseWheel, Circulate, FocusOut, Property, | |
906 | Colormap, Gravity Reparent, Configure, KeyPress, Key, | |
907 | Unmap, Deactivate, KeyRelease Visibility, Destroy, | |
908 | Leave and DETAIL is the button number for ButtonPress, | |
909 | ButtonRelease and DETAIL is the Keysym for KeyPress and | |
910 | KeyRelease. Examples are | |
911 | <Control-Button-1> for pressing Control and mouse button 1 or | |
912 | <Alt-A> for pressing A and the Alt key (KeyPress can be omitted). | |
913 | An event pattern can also be a virtual event of the form | |
914 | <<AString>> where AString can be arbitrary. This | |
915 | event can be generated by event_generate. | |
916 | If events are concatenated they must appear shortly | |
917 | after each other. | |
918 | ||
919 | FUNC will be called if the event sequence occurs with an | |
920 | instance of Event as argument. If the return value of FUNC is | |
921 | "break" no further bound function is invoked. | |
922 | ||
923 | An additional boolean parameter ADD specifies whether FUNC will | |
924 | be called additionally to the other bound function or whether | |
925 | it will replace the previous function. | |
926 | ||
927 | Bind will return an identifier to allow deletion of the bound function with | |
928 | unbind without memory leak. | |
929 | ||
930 | If FUNC or SEQUENCE is omitted the bound function or list | |
931 | of bound events are returned.""" | |
932 | ||
933 | return self._bind(('bind', self._w), sequence, func, add) | |
934 | def unbind(self, sequence, funcid=None): | |
935 | """Unbind for this widget for event SEQUENCE the | |
936 | function identified with FUNCID.""" | |
937 | self.tk.call('bind', self._w, sequence, '') | |
938 | if funcid: | |
939 | self.deletecommand(funcid) | |
940 | def bind_all(self, sequence=None, func=None, add=None): | |
941 | """Bind to all widgets at an event SEQUENCE a call to function FUNC. | |
942 | An additional boolean parameter ADD specifies whether FUNC will | |
943 | be called additionally to the other bound function or whether | |
944 | it will replace the previous function. See bind for the return value.""" | |
945 | return self._bind(('bind', 'all'), sequence, func, add, 0) | |
946 | def unbind_all(self, sequence): | |
947 | """Unbind for all widgets for event SEQUENCE all functions.""" | |
948 | self.tk.call('bind', 'all' , sequence, '') | |
949 | def bind_class(self, className, sequence=None, func=None, add=None): | |
950 | ||
951 | """Bind to widgets with bindtag CLASSNAME at event | |
952 | SEQUENCE a call of function FUNC. An additional | |
953 | boolean parameter ADD specifies whether FUNC will be | |
954 | called additionally to the other bound function or | |
955 | whether it will replace the previous function. See bind for | |
956 | the return value.""" | |
957 | ||
958 | return self._bind(('bind', className), sequence, func, add, 0) | |
959 | def unbind_class(self, className, sequence): | |
960 | """Unbind for a all widgets with bindtag CLASSNAME for event SEQUENCE | |
961 | all functions.""" | |
962 | self.tk.call('bind', className , sequence, '') | |
963 | def mainloop(self, n=0): | |
964 | """Call the mainloop of Tk.""" | |
965 | self.tk.mainloop(n) | |
966 | def quit(self): | |
967 | """Quit the Tcl interpreter. All widgets will be destroyed.""" | |
968 | self.tk.quit() | |
969 | def _getints(self, string): | |
970 | """Internal function.""" | |
971 | if string: | |
972 | return tuple(map(getint, self.tk.splitlist(string))) | |
973 | def _getdoubles(self, string): | |
974 | """Internal function.""" | |
975 | if string: | |
976 | return tuple(map(getdouble, self.tk.splitlist(string))) | |
977 | def _getboolean(self, string): | |
978 | """Internal function.""" | |
979 | if string: | |
980 | return self.tk.getboolean(string) | |
981 | def _displayof(self, displayof): | |
982 | """Internal function.""" | |
983 | if displayof: | |
984 | return ('-displayof', displayof) | |
985 | if displayof is None: | |
986 | return ('-displayof', self._w) | |
987 | return () | |
988 | def _options(self, cnf, kw = None): | |
989 | """Internal function.""" | |
990 | if kw: | |
991 | cnf = _cnfmerge((cnf, kw)) | |
992 | else: | |
993 | cnf = _cnfmerge(cnf) | |
994 | res = () | |
995 | for k, v in cnf.items(): | |
996 | if v is not None: | |
997 | if k[-1] == '_': k = k[:-1] | |
998 | if callable(v): | |
999 | v = self._register(v) | |
1000 | res = res + ('-'+k, v) | |
1001 | return res | |
1002 | def nametowidget(self, name): | |
1003 | """Return the Tkinter instance of a widget identified by | |
1004 | its Tcl name NAME.""" | |
1005 | w = self | |
1006 | if name[0] == '.': | |
1007 | w = w._root() | |
1008 | name = name[1:] | |
1009 | while name: | |
1010 | i = name.find('.') | |
1011 | if i >= 0: | |
1012 | name, tail = name[:i], name[i+1:] | |
1013 | else: | |
1014 | tail = '' | |
1015 | w = w.children[name] | |
1016 | name = tail | |
1017 | return w | |
1018 | _nametowidget = nametowidget | |
1019 | def _register(self, func, subst=None, needcleanup=1): | |
1020 | """Return a newly created Tcl function. If this | |
1021 | function is called, the Python function FUNC will | |
1022 | be executed. An optional function SUBST can | |
1023 | be given which will be executed before FUNC.""" | |
1024 | f = CallWrapper(func, subst, self).__call__ | |
1025 | name = repr(id(f)) | |
1026 | try: | |
1027 | func = func.im_func | |
1028 | except AttributeError: | |
1029 | pass | |
1030 | try: | |
1031 | name = name + func.__name__ | |
1032 | except AttributeError: | |
1033 | pass | |
1034 | self.tk.createcommand(name, f) | |
1035 | if needcleanup: | |
1036 | if self._tclCommands is None: | |
1037 | self._tclCommands = [] | |
1038 | self._tclCommands.append(name) | |
1039 | #print '+ Tkinter created command', name | |
1040 | return name | |
1041 | register = _register | |
1042 | def _root(self): | |
1043 | """Internal function.""" | |
1044 | w = self | |
1045 | while w.master: w = w.master | |
1046 | return w | |
1047 | _subst_format = ('%#', '%b', '%f', '%h', '%k', | |
1048 | '%s', '%t', '%w', '%x', '%y', | |
1049 | '%A', '%E', '%K', '%N', '%W', '%T', '%X', '%Y', '%D') | |
1050 | _subst_format_str = " ".join(_subst_format) | |
1051 | def _substitute(self, *args): | |
1052 | """Internal function.""" | |
1053 | if len(args) != len(self._subst_format): return args | |
1054 | getboolean = self.tk.getboolean | |
1055 | ||
1056 | getint = int | |
1057 | def getint_event(s): | |
1058 | """Tk changed behavior in 8.4.2, returning "??" rather more often.""" | |
1059 | try: | |
1060 | return int(s) | |
1061 | except ValueError: | |
1062 | return s | |
1063 | ||
1064 | nsign, b, f, h, k, s, t, w, x, y, A, E, K, N, W, T, X, Y, D = args | |
1065 | # Missing: (a, c, d, m, o, v, B, R) | |
1066 | e = Event() | |
1067 | # serial field: valid vor all events | |
1068 | # number of button: ButtonPress and ButtonRelease events only | |
1069 | # height field: Configure, ConfigureRequest, Create, | |
1070 | # ResizeRequest, and Expose events only | |
1071 | # keycode field: KeyPress and KeyRelease events only | |
1072 | # time field: "valid for events that contain a time field" | |
1073 | # width field: Configure, ConfigureRequest, Create, ResizeRequest, | |
1074 | # and Expose events only | |
1075 | # x field: "valid for events that contain a x field" | |
1076 | # y field: "valid for events that contain a y field" | |
1077 | # keysym as decimal: KeyPress and KeyRelease events only | |
1078 | # x_root, y_root fields: ButtonPress, ButtonRelease, KeyPress, | |
1079 | # KeyRelease,and Motion events | |
1080 | e.serial = getint(nsign) | |
1081 | e.num = getint_event(b) | |
1082 | try: e.focus = getboolean(f) | |
1083 | except TclError: pass | |
1084 | e.height = getint_event(h) | |
1085 | e.keycode = getint_event(k) | |
1086 | e.state = getint_event(s) | |
1087 | e.time = getint_event(t) | |
1088 | e.width = getint_event(w) | |
1089 | e.x = getint_event(x) | |
1090 | e.y = getint_event(y) | |
1091 | e.char = A | |
1092 | try: e.send_event = getboolean(E) | |
1093 | except TclError: pass | |
1094 | e.keysym = K | |
1095 | e.keysym_num = getint_event(N) | |
1096 | e.type = T | |
1097 | try: | |
1098 | e.widget = self._nametowidget(W) | |
1099 | except KeyError: | |
1100 | e.widget = W | |
1101 | e.x_root = getint_event(X) | |
1102 | e.y_root = getint_event(Y) | |
1103 | try: | |
1104 | e.delta = getint(D) | |
1105 | except ValueError: | |
1106 | e.delta = 0 | |
1107 | return (e,) | |
1108 | def _report_exception(self): | |
1109 | """Internal function.""" | |
1110 | import sys | |
1111 | exc, val, tb = sys.exc_type, sys.exc_value, sys.exc_traceback | |
1112 | root = self._root() | |
1113 | root.report_callback_exception(exc, val, tb) | |
1114 | def _configure(self, cmd, cnf, kw): | |
1115 | """Internal function.""" | |
1116 | if kw: | |
1117 | cnf = _cnfmerge((cnf, kw)) | |
1118 | elif cnf: | |
1119 | cnf = _cnfmerge(cnf) | |
1120 | if cnf is None: | |
1121 | cnf = {} | |
1122 | for x in self.tk.split( | |
1123 | self.tk.call(_flatten((self._w, cmd)))): | |
1124 | cnf[x[0][1:]] = (x[0][1:],) + x[1:] | |
1125 | return cnf | |
1126 | if type(cnf) is StringType: | |
1127 | x = self.tk.split( | |
1128 | self.tk.call(_flatten((self._w, cmd, '-'+cnf)))) | |
1129 | return (x[0][1:],) + x[1:] | |
1130 | self.tk.call(_flatten((self._w, cmd)) + self._options(cnf)) | |
1131 | # These used to be defined in Widget: | |
1132 | def configure(self, cnf=None, **kw): | |
1133 | """Configure resources of a widget. | |
1134 | ||
1135 | The values for resources are specified as keyword | |
1136 | arguments. To get an overview about | |
1137 | the allowed keyword arguments call the method keys. | |
1138 | """ | |
1139 | return self._configure('configure', cnf, kw) | |
1140 | config = configure | |
1141 | def cget(self, key): | |
1142 | """Return the resource value for a KEY given as string.""" | |
1143 | return self.tk.call(self._w, 'cget', '-' + key) | |
1144 | __getitem__ = cget | |
1145 | def __setitem__(self, key, value): | |
1146 | self.configure({key: value}) | |
1147 | def keys(self): | |
1148 | """Return a list of all resource names of this widget.""" | |
1149 | return map(lambda x: x[0][1:], | |
1150 | self.tk.split(self.tk.call(self._w, 'configure'))) | |
1151 | def __str__(self): | |
1152 | """Return the window path name of this widget.""" | |
1153 | return self._w | |
1154 | # Pack methods that apply to the master | |
1155 | _noarg_ = ['_noarg_'] | |
1156 | def pack_propagate(self, flag=_noarg_): | |
1157 | """Set or get the status for propagation of geometry information. | |
1158 | ||
1159 | A boolean argument specifies whether the geometry information | |
1160 | of the slaves will determine the size of this widget. If no argument | |
1161 | is given the current setting will be returned. | |
1162 | """ | |
1163 | if flag is Misc._noarg_: | |
1164 | return self._getboolean(self.tk.call( | |
1165 | 'pack', 'propagate', self._w)) | |
1166 | else: | |
1167 | self.tk.call('pack', 'propagate', self._w, flag) | |
1168 | propagate = pack_propagate | |
1169 | def pack_slaves(self): | |
1170 | """Return a list of all slaves of this widget | |
1171 | in its packing order.""" | |
1172 | return map(self._nametowidget, | |
1173 | self.tk.splitlist( | |
1174 | self.tk.call('pack', 'slaves', self._w))) | |
1175 | slaves = pack_slaves | |
1176 | # Place method that applies to the master | |
1177 | def place_slaves(self): | |
1178 | """Return a list of all slaves of this widget | |
1179 | in its packing order.""" | |
1180 | return map(self._nametowidget, | |
1181 | self.tk.splitlist( | |
1182 | self.tk.call( | |
1183 | 'place', 'slaves', self._w))) | |
1184 | # Grid methods that apply to the master | |
1185 | def grid_bbox(self, column=None, row=None, col2=None, row2=None): | |
1186 | """Return a tuple of integer coordinates for the bounding | |
1187 | box of this widget controlled by the geometry manager grid. | |
1188 | ||
1189 | If COLUMN, ROW is given the bounding box applies from | |
1190 | the cell with row and column 0 to the specified | |
1191 | cell. If COL2 and ROW2 are given the bounding box | |
1192 | starts at that cell. | |
1193 | ||
1194 | The returned integers specify the offset of the upper left | |
1195 | corner in the master widget and the width and height. | |
1196 | """ | |
1197 | args = ('grid', 'bbox', self._w) | |
1198 | if column is not None and row is not None: | |
1199 | args = args + (column, row) | |
1200 | if col2 is not None and row2 is not None: | |
1201 | args = args + (col2, row2) | |
1202 | return self._getints(self.tk.call(*args)) or None | |
1203 | ||
1204 | bbox = grid_bbox | |
1205 | def _grid_configure(self, command, index, cnf, kw): | |
1206 | """Internal function.""" | |
1207 | if type(cnf) is StringType and not kw: | |
1208 | if cnf[-1:] == '_': | |
1209 | cnf = cnf[:-1] | |
1210 | if cnf[:1] != '-': | |
1211 | cnf = '-'+cnf | |
1212 | options = (cnf,) | |
1213 | else: | |
1214 | options = self._options(cnf, kw) | |
1215 | if not options: | |
1216 | res = self.tk.call('grid', | |
1217 | command, self._w, index) | |
1218 | words = self.tk.splitlist(res) | |
1219 | dict = {} | |
1220 | for i in range(0, len(words), 2): | |
1221 | key = words[i][1:] | |
1222 | value = words[i+1] | |
1223 | if not value: | |
1224 | value = None | |
1225 | elif '.' in value: | |
1226 | value = getdouble(value) | |
1227 | else: | |
1228 | value = getint(value) | |
1229 | dict[key] = value | |
1230 | return dict | |
1231 | res = self.tk.call( | |
1232 | ('grid', command, self._w, index) | |
1233 | + options) | |
1234 | if len(options) == 1: | |
1235 | if not res: return None | |
1236 | # In Tk 7.5, -width can be a float | |
1237 | if '.' in res: return getdouble(res) | |
1238 | return getint(res) | |
1239 | def grid_columnconfigure(self, index, cnf={}, **kw): | |
1240 | """Configure column INDEX of a grid. | |
1241 | ||
1242 | Valid resources are minsize (minimum size of the column), | |
1243 | weight (how much does additional space propagate to this column) | |
1244 | and pad (how much space to let additionally).""" | |
1245 | return self._grid_configure('columnconfigure', index, cnf, kw) | |
1246 | columnconfigure = grid_columnconfigure | |
1247 | def grid_location(self, x, y): | |
1248 | """Return a tuple of column and row which identify the cell | |
1249 | at which the pixel at position X and Y inside the master | |
1250 | widget is located.""" | |
1251 | return self._getints( | |
1252 | self.tk.call( | |
1253 | 'grid', 'location', self._w, x, y)) or None | |
1254 | def grid_propagate(self, flag=_noarg_): | |
1255 | """Set or get the status for propagation of geometry information. | |
1256 | ||
1257 | A boolean argument specifies whether the geometry information | |
1258 | of the slaves will determine the size of this widget. If no argument | |
1259 | is given, the current setting will be returned. | |
1260 | """ | |
1261 | if flag is Misc._noarg_: | |
1262 | return self._getboolean(self.tk.call( | |
1263 | 'grid', 'propagate', self._w)) | |
1264 | else: | |
1265 | self.tk.call('grid', 'propagate', self._w, flag) | |
1266 | def grid_rowconfigure(self, index, cnf={}, **kw): | |
1267 | """Configure row INDEX of a grid. | |
1268 | ||
1269 | Valid resources are minsize (minimum size of the row), | |
1270 | weight (how much does additional space propagate to this row) | |
1271 | and pad (how much space to let additionally).""" | |
1272 | return self._grid_configure('rowconfigure', index, cnf, kw) | |
1273 | rowconfigure = grid_rowconfigure | |
1274 | def grid_size(self): | |
1275 | """Return a tuple of the number of column and rows in the grid.""" | |
1276 | return self._getints( | |
1277 | self.tk.call('grid', 'size', self._w)) or None | |
1278 | size = grid_size | |
1279 | def grid_slaves(self, row=None, column=None): | |
1280 | """Return a list of all slaves of this widget | |
1281 | in its packing order.""" | |
1282 | args = () | |
1283 | if row is not None: | |
1284 | args = args + ('-row', row) | |
1285 | if column is not None: | |
1286 | args = args + ('-column', column) | |
1287 | return map(self._nametowidget, | |
1288 | self.tk.splitlist(self.tk.call( | |
1289 | ('grid', 'slaves', self._w) + args))) | |
1290 | ||
1291 | # Support for the "event" command, new in Tk 4.2. | |
1292 | # By Case Roole. | |
1293 | ||
1294 | def event_add(self, virtual, *sequences): | |
1295 | """Bind a virtual event VIRTUAL (of the form <<Name>>) | |
1296 | to an event SEQUENCE such that the virtual event is triggered | |
1297 | whenever SEQUENCE occurs.""" | |
1298 | args = ('event', 'add', virtual) + sequences | |
1299 | self.tk.call(args) | |
1300 | ||
1301 | def event_delete(self, virtual, *sequences): | |
1302 | """Unbind a virtual event VIRTUAL from SEQUENCE.""" | |
1303 | args = ('event', 'delete', virtual) + sequences | |
1304 | self.tk.call(args) | |
1305 | ||
1306 | def event_generate(self, sequence, **kw): | |
1307 | """Generate an event SEQUENCE. Additional | |
1308 | keyword arguments specify parameter of the event | |
1309 | (e.g. x, y, rootx, rooty).""" | |
1310 | args = ('event', 'generate', self._w, sequence) | |
1311 | for k, v in kw.items(): | |
1312 | args = args + ('-%s' % k, str(v)) | |
1313 | self.tk.call(args) | |
1314 | ||
1315 | def event_info(self, virtual=None): | |
1316 | """Return a list of all virtual events or the information | |
1317 | about the SEQUENCE bound to the virtual event VIRTUAL.""" | |
1318 | return self.tk.splitlist( | |
1319 | self.tk.call('event', 'info', virtual)) | |
1320 | ||
1321 | # Image related commands | |
1322 | ||
1323 | def image_names(self): | |
1324 | """Return a list of all existing image names.""" | |
1325 | return self.tk.call('image', 'names') | |
1326 | ||
1327 | def image_types(self): | |
1328 | """Return a list of all available image types (e.g. phote bitmap).""" | |
1329 | return self.tk.call('image', 'types') | |
1330 | ||
1331 | ||
1332 | class CallWrapper: | |
1333 | """Internal class. Stores function to call when some user | |
1334 | defined Tcl function is called e.g. after an event occurred.""" | |
1335 | def __init__(self, func, subst, widget): | |
1336 | """Store FUNC, SUBST and WIDGET as members.""" | |
1337 | self.func = func | |
1338 | self.subst = subst | |
1339 | self.widget = widget | |
1340 | def __call__(self, *args): | |
1341 | """Apply first function SUBST to arguments, than FUNC.""" | |
1342 | try: | |
1343 | if self.subst: | |
1344 | args = self.subst(*args) | |
1345 | return self.func(*args) | |
1346 | except SystemExit, msg: | |
1347 | raise SystemExit, msg | |
1348 | except: | |
1349 | self.widget._report_exception() | |
1350 | ||
1351 | ||
1352 | class Wm: | |
1353 | """Provides functions for the communication with the window manager.""" | |
1354 | ||
1355 | def wm_aspect(self, | |
1356 | minNumer=None, minDenom=None, | |
1357 | maxNumer=None, maxDenom=None): | |
1358 | """Instruct the window manager to set the aspect ratio (width/height) | |
1359 | of this widget to be between MINNUMER/MINDENOM and MAXNUMER/MAXDENOM. Return a tuple | |
1360 | of the actual values if no argument is given.""" | |
1361 | return self._getints( | |
1362 | self.tk.call('wm', 'aspect', self._w, | |
1363 | minNumer, minDenom, | |
1364 | maxNumer, maxDenom)) | |
1365 | aspect = wm_aspect | |
1366 | ||
1367 | def wm_attributes(self, *args): | |
1368 | """This subcommand returns or sets platform specific attributes | |
1369 | ||
1370 | The first form returns a list of the platform specific flags and | |
1371 | their values. The second form returns the value for the specific | |
1372 | option. The third form sets one or more of the values. The values | |
1373 | are as follows: | |
1374 | ||
1375 | On Windows, -disabled gets or sets whether the window is in a | |
1376 | disabled state. -toolwindow gets or sets the style of the window | |
1377 | to toolwindow (as defined in the MSDN). -topmost gets or sets | |
1378 | whether this is a topmost window (displays above all other | |
1379 | windows). | |
1380 | ||
1381 | On Macintosh, XXXXX | |
1382 | ||
1383 | On Unix, there are currently no special attribute values. | |
1384 | """ | |
1385 | args = ('wm', 'attributes', self._w) + args | |
1386 | return self.tk.call(args) | |
1387 | attributes=wm_attributes | |
1388 | ||
1389 | def wm_client(self, name=None): | |
1390 | """Store NAME in WM_CLIENT_MACHINE property of this widget. Return | |
1391 | current value.""" | |
1392 | return self.tk.call('wm', 'client', self._w, name) | |
1393 | client = wm_client | |
1394 | def wm_colormapwindows(self, *wlist): | |
1395 | """Store list of window names (WLIST) into WM_COLORMAPWINDOWS property | |
1396 | of this widget. This list contains windows whose colormaps differ from their | |
1397 | parents. Return current list of widgets if WLIST is empty.""" | |
1398 | if len(wlist) > 1: | |
1399 | wlist = (wlist,) # Tk needs a list of windows here | |
1400 | args = ('wm', 'colormapwindows', self._w) + wlist | |
1401 | return map(self._nametowidget, self.tk.call(args)) | |
1402 | colormapwindows = wm_colormapwindows | |
1403 | def wm_command(self, value=None): | |
1404 | """Store VALUE in WM_COMMAND property. It is the command | |
1405 | which shall be used to invoke the application. Return current | |
1406 | command if VALUE is None.""" | |
1407 | return self.tk.call('wm', 'command', self._w, value) | |
1408 | command = wm_command | |
1409 | def wm_deiconify(self): | |
1410 | """Deiconify this widget. If it was never mapped it will not be mapped. | |
1411 | On Windows it will raise this widget and give it the focus.""" | |
1412 | return self.tk.call('wm', 'deiconify', self._w) | |
1413 | deiconify = wm_deiconify | |
1414 | def wm_focusmodel(self, model=None): | |
1415 | """Set focus model to MODEL. "active" means that this widget will claim | |
1416 | the focus itself, "passive" means that the window manager shall give | |
1417 | the focus. Return current focus model if MODEL is None.""" | |
1418 | return self.tk.call('wm', 'focusmodel', self._w, model) | |
1419 | focusmodel = wm_focusmodel | |
1420 | def wm_frame(self): | |
1421 | """Return identifier for decorative frame of this widget if present.""" | |
1422 | return self.tk.call('wm', 'frame', self._w) | |
1423 | frame = wm_frame | |
1424 | def wm_geometry(self, newGeometry=None): | |
1425 | """Set geometry to NEWGEOMETRY of the form =widthxheight+x+y. Return | |
1426 | current value if None is given.""" | |
1427 | return self.tk.call('wm', 'geometry', self._w, newGeometry) | |
1428 | geometry = wm_geometry | |
1429 | def wm_grid(self, | |
1430 | baseWidth=None, baseHeight=None, | |
1431 | widthInc=None, heightInc=None): | |
1432 | """Instruct the window manager that this widget shall only be | |
1433 | resized on grid boundaries. WIDTHINC and HEIGHTINC are the width and | |
1434 | height of a grid unit in pixels. BASEWIDTH and BASEHEIGHT are the | |
1435 | number of grid units requested in Tk_GeometryRequest.""" | |
1436 | return self._getints(self.tk.call( | |
1437 | 'wm', 'grid', self._w, | |
1438 | baseWidth, baseHeight, widthInc, heightInc)) | |
1439 | grid = wm_grid | |
1440 | def wm_group(self, pathName=None): | |
1441 | """Set the group leader widgets for related widgets to PATHNAME. Return | |
1442 | the group leader of this widget if None is given.""" | |
1443 | return self.tk.call('wm', 'group', self._w, pathName) | |
1444 | group = wm_group | |
1445 | def wm_iconbitmap(self, bitmap=None): | |
1446 | """Set bitmap for the iconified widget to BITMAP. Return | |
1447 | the bitmap if None is given.""" | |
1448 | return self.tk.call('wm', 'iconbitmap', self._w, bitmap) | |
1449 | iconbitmap = wm_iconbitmap | |
1450 | def wm_iconify(self): | |
1451 | """Display widget as icon.""" | |
1452 | return self.tk.call('wm', 'iconify', self._w) | |
1453 | iconify = wm_iconify | |
1454 | def wm_iconmask(self, bitmap=None): | |
1455 | """Set mask for the icon bitmap of this widget. Return the | |
1456 | mask if None is given.""" | |
1457 | return self.tk.call('wm', 'iconmask', self._w, bitmap) | |
1458 | iconmask = wm_iconmask | |
1459 | def wm_iconname(self, newName=None): | |
1460 | """Set the name of the icon for this widget. Return the name if | |
1461 | None is given.""" | |
1462 | return self.tk.call('wm', 'iconname', self._w, newName) | |
1463 | iconname = wm_iconname | |
1464 | def wm_iconposition(self, x=None, y=None): | |
1465 | """Set the position of the icon of this widget to X and Y. Return | |
1466 | a tuple of the current values of X and X if None is given.""" | |
1467 | return self._getints(self.tk.call( | |
1468 | 'wm', 'iconposition', self._w, x, y)) | |
1469 | iconposition = wm_iconposition | |
1470 | def wm_iconwindow(self, pathName=None): | |
1471 | """Set widget PATHNAME to be displayed instead of icon. Return the current | |
1472 | value if None is given.""" | |
1473 | return self.tk.call('wm', 'iconwindow', self._w, pathName) | |
1474 | iconwindow = wm_iconwindow | |
1475 | def wm_maxsize(self, width=None, height=None): | |
1476 | """Set max WIDTH and HEIGHT for this widget. If the window is gridded | |
1477 | the values are given in grid units. Return the current values if None | |
1478 | is given.""" | |
1479 | return self._getints(self.tk.call( | |
1480 | 'wm', 'maxsize', self._w, width, height)) | |
1481 | maxsize = wm_maxsize | |
1482 | def wm_minsize(self, width=None, height=None): | |
1483 | """Set min WIDTH and HEIGHT for this widget. If the window is gridded | |
1484 | the values are given in grid units. Return the current values if None | |
1485 | is given.""" | |
1486 | return self._getints(self.tk.call( | |
1487 | 'wm', 'minsize', self._w, width, height)) | |
1488 | minsize = wm_minsize | |
1489 | def wm_overrideredirect(self, boolean=None): | |
1490 | """Instruct the window manager to ignore this widget | |
1491 | if BOOLEAN is given with 1. Return the current value if None | |
1492 | is given.""" | |
1493 | return self._getboolean(self.tk.call( | |
1494 | 'wm', 'overrideredirect', self._w, boolean)) | |
1495 | overrideredirect = wm_overrideredirect | |
1496 | def wm_positionfrom(self, who=None): | |
1497 | """Instruct the window manager that the position of this widget shall | |
1498 | be defined by the user if WHO is "user", and by its own policy if WHO is | |
1499 | "program".""" | |
1500 | return self.tk.call('wm', 'positionfrom', self._w, who) | |
1501 | positionfrom = wm_positionfrom | |
1502 | def wm_protocol(self, name=None, func=None): | |
1503 | """Bind function FUNC to command NAME for this widget. | |
1504 | Return the function bound to NAME if None is given. NAME could be | |
1505 | e.g. "WM_SAVE_YOURSELF" or "WM_DELETE_WINDOW".""" | |
1506 | if callable(func): | |
1507 | command = self._register(func) | |
1508 | else: | |
1509 | command = func | |
1510 | return self.tk.call( | |
1511 | 'wm', 'protocol', self._w, name, command) | |
1512 | protocol = wm_protocol | |
1513 | def wm_resizable(self, width=None, height=None): | |
1514 | """Instruct the window manager whether this width can be resized | |
1515 | in WIDTH or HEIGHT. Both values are boolean values.""" | |
1516 | return self.tk.call('wm', 'resizable', self._w, width, height) | |
1517 | resizable = wm_resizable | |
1518 | def wm_sizefrom(self, who=None): | |
1519 | """Instruct the window manager that the size of this widget shall | |
1520 | be defined by the user if WHO is "user", and by its own policy if WHO is | |
1521 | "program".""" | |
1522 | return self.tk.call('wm', 'sizefrom', self._w, who) | |
1523 | sizefrom = wm_sizefrom | |
1524 | def wm_state(self, newstate=None): | |
1525 | """Query or set the state of this widget as one of normal, icon, | |
1526 | iconic (see wm_iconwindow), withdrawn, or zoomed (Windows only).""" | |
1527 | return self.tk.call('wm', 'state', self._w, newstate) | |
1528 | state = wm_state | |
1529 | def wm_title(self, string=None): | |
1530 | """Set the title of this widget.""" | |
1531 | return self.tk.call('wm', 'title', self._w, string) | |
1532 | title = wm_title | |
1533 | def wm_transient(self, master=None): | |
1534 | """Instruct the window manager that this widget is transient | |
1535 | with regard to widget MASTER.""" | |
1536 | return self.tk.call('wm', 'transient', self._w, master) | |
1537 | transient = wm_transient | |
1538 | def wm_withdraw(self): | |
1539 | """Withdraw this widget from the screen such that it is unmapped | |
1540 | and forgotten by the window manager. Re-draw it with wm_deiconify.""" | |
1541 | return self.tk.call('wm', 'withdraw', self._w) | |
1542 | withdraw = wm_withdraw | |
1543 | ||
1544 | ||
1545 | class Tk(Misc, Wm): | |
1546 | """Toplevel widget of Tk which represents mostly the main window | |
1547 | of an appliation. It has an associated Tcl interpreter.""" | |
1548 | _w = '.' | |
1549 | def __init__(self, screenName=None, baseName=None, className='Tk', | |
1550 | useTk=1, sync=0, use=None): | |
1551 | """Return a new Toplevel widget on screen SCREENNAME. A new Tcl interpreter will | |
1552 | be created. BASENAME will be used for the identification of the profile file (see | |
1553 | readprofile). | |
1554 | It is constructed from sys.argv[0] without extensions if None is given. CLASSNAME | |
1555 | is the name of the widget class.""" | |
1556 | self.master = None | |
1557 | self.children = {} | |
1558 | self._tkloaded = 0 | |
1559 | # to avoid recursions in the getattr code in case of failure, we | |
1560 | # ensure that self.tk is always _something_. | |
1561 | self.tk = None | |
1562 | if baseName is None: | |
1563 | import sys, os | |
1564 | baseName = os.path.basename(sys.argv[0]) | |
1565 | baseName, ext = os.path.splitext(baseName) | |
1566 | if ext not in ('.py', '.pyc', '.pyo'): | |
1567 | baseName = baseName + ext | |
1568 | interactive = 0 | |
1569 | self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use) | |
1570 | if useTk: | |
1571 | self._loadtk() | |
1572 | self.readprofile(baseName, className) | |
1573 | def loadtk(self): | |
1574 | if not self._tkloaded: | |
1575 | self.tk.loadtk() | |
1576 | self._loadtk() | |
1577 | def _loadtk(self): | |
1578 | self._tkloaded = 1 | |
1579 | global _default_root | |
1580 | if _MacOS and hasattr(_MacOS, 'SchedParams'): | |
1581 | # Disable event scanning except for Command-Period | |
1582 | _MacOS.SchedParams(1, 0) | |
1583 | # Work around nasty MacTk bug | |
1584 | # XXX Is this one still needed? | |
1585 | self.update() | |
1586 | # Version sanity checks | |
1587 | tk_version = self.tk.getvar('tk_version') | |
1588 | if tk_version != _tkinter.TK_VERSION: | |
1589 | raise RuntimeError, \ | |
1590 | "tk.h version (%s) doesn't match libtk.a version (%s)" \ | |
1591 | % (_tkinter.TK_VERSION, tk_version) | |
1592 | # Under unknown circumstances, tcl_version gets coerced to float | |
1593 | tcl_version = str(self.tk.getvar('tcl_version')) | |
1594 | if tcl_version != _tkinter.TCL_VERSION: | |
1595 | raise RuntimeError, \ | |
1596 | "tcl.h version (%s) doesn't match libtcl.a version (%s)" \ | |
1597 | % (_tkinter.TCL_VERSION, tcl_version) | |
1598 | if TkVersion < 4.0: | |
1599 | raise RuntimeError, \ | |
1600 | "Tk 4.0 or higher is required; found Tk %s" \ | |
1601 | % str(TkVersion) | |
1602 | # Create and register the tkerror and exit commands | |
1603 | # We need to inline parts of _register here, _ register | |
1604 | # would register differently-named commands. | |
1605 | if self._tclCommands is None: | |
1606 | self._tclCommands = [] | |
1607 | self.tk.createcommand('tkerror', _tkerror) | |
1608 | self.tk.createcommand('exit', _exit) | |
1609 | self._tclCommands.append('tkerror') | |
1610 | self._tclCommands.append('exit') | |
1611 | if _support_default_root and not _default_root: | |
1612 | _default_root = self | |
1613 | self.protocol("WM_DELETE_WINDOW", self.destroy) | |
1614 | def destroy(self): | |
1615 | """Destroy this and all descendants widgets. This will | |
1616 | end the application of this Tcl interpreter.""" | |
1617 | for c in self.children.values(): c.destroy() | |
1618 | self.tk.call('destroy', self._w) | |
1619 | Misc.destroy(self) | |
1620 | global _default_root | |
1621 | if _support_default_root and _default_root is self: | |
1622 | _default_root = None | |
1623 | def readprofile(self, baseName, className): | |
1624 | """Internal function. It reads BASENAME.tcl and CLASSNAME.tcl into | |
1625 | the Tcl Interpreter and calls execfile on BASENAME.py and CLASSNAME.py if | |
1626 | such a file exists in the home directory.""" | |
1627 | import os | |
1628 | if os.environ.has_key('HOME'): home = os.environ['HOME'] | |
1629 | else: home = os.curdir | |
1630 | class_tcl = os.path.join(home, '.%s.tcl' % className) | |
1631 | class_py = os.path.join(home, '.%s.py' % className) | |
1632 | base_tcl = os.path.join(home, '.%s.tcl' % baseName) | |
1633 | base_py = os.path.join(home, '.%s.py' % baseName) | |
1634 | dir = {'self': self} | |
1635 | exec 'from Tkinter import *' in dir | |
1636 | if os.path.isfile(class_tcl): | |
1637 | self.tk.call('source', class_tcl) | |
1638 | if os.path.isfile(class_py): | |
1639 | execfile(class_py, dir) | |
1640 | if os.path.isfile(base_tcl): | |
1641 | self.tk.call('source', base_tcl) | |
1642 | if os.path.isfile(base_py): | |
1643 | execfile(base_py, dir) | |
1644 | def report_callback_exception(self, exc, val, tb): | |
1645 | """Internal function. It reports exception on sys.stderr.""" | |
1646 | import traceback, sys | |
1647 | sys.stderr.write("Exception in Tkinter callback\n") | |
1648 | sys.last_type = exc | |
1649 | sys.last_value = val | |
1650 | sys.last_traceback = tb | |
1651 | traceback.print_exception(exc, val, tb) | |
1652 | def __getattr__(self, attr): | |
1653 | "Delegate attribute access to the interpreter object" | |
1654 | return getattr(self.tk, attr) | |
1655 | ||
1656 | # Ideally, the classes Pack, Place and Grid disappear, the | |
1657 | # pack/place/grid methods are defined on the Widget class, and | |
1658 | # everybody uses w.pack_whatever(...) instead of Pack.whatever(w, | |
1659 | # ...), with pack(), place() and grid() being short for | |
1660 | # pack_configure(), place_configure() and grid_columnconfigure(), and | |
1661 | # forget() being short for pack_forget(). As a practical matter, I'm | |
1662 | # afraid that there is too much code out there that may be using the | |
1663 | # Pack, Place or Grid class, so I leave them intact -- but only as | |
1664 | # backwards compatibility features. Also note that those methods that | |
1665 | # take a master as argument (e.g. pack_propagate) have been moved to | |
1666 | # the Misc class (which now incorporates all methods common between | |
1667 | # toplevel and interior widgets). Again, for compatibility, these are | |
1668 | # copied into the Pack, Place or Grid class. | |
1669 | ||
1670 | ||
1671 | def Tcl(screenName=None, baseName=None, className='Tk', useTk=0): | |
1672 | return Tk(screenName, baseName, className, useTk) | |
1673 | ||
1674 | class Pack: | |
1675 | """Geometry manager Pack. | |
1676 | ||
1677 | Base class to use the methods pack_* in every widget.""" | |
1678 | def pack_configure(self, cnf={}, **kw): | |
1679 | """Pack a widget in the parent widget. Use as options: | |
1680 | after=widget - pack it after you have packed widget | |
1681 | anchor=NSEW (or subset) - position widget according to | |
1682 | given direction | |
1683 | before=widget - pack it before you will pack widget | |
1684 | expand=bool - expand widget if parent size grows | |
1685 | fill=NONE or X or Y or BOTH - fill widget if widget grows | |
1686 | in=master - use master to contain this widget | |
1687 | ipadx=amount - add internal padding in x direction | |
1688 | ipady=amount - add internal padding in y direction | |
1689 | padx=amount - add padding in x direction | |
1690 | pady=amount - add padding in y direction | |
1691 | side=TOP or BOTTOM or LEFT or RIGHT - where to add this widget. | |
1692 | """ | |
1693 | self.tk.call( | |
1694 | ('pack', 'configure', self._w) | |
1695 | + self._options(cnf, kw)) | |
1696 | pack = configure = config = pack_configure | |
1697 | def pack_forget(self): | |
1698 | """Unmap this widget and do not use it for the packing order.""" | |
1699 | self.tk.call('pack', 'forget', self._w) | |
1700 | forget = pack_forget | |
1701 | def pack_info(self): | |
1702 | """Return information about the packing options | |
1703 | for this widget.""" | |
1704 | words = self.tk.splitlist( | |
1705 | self.tk.call('pack', 'info', self._w)) | |
1706 | dict = {} | |
1707 | for i in range(0, len(words), 2): | |
1708 | key = words[i][1:] | |
1709 | value = words[i+1] | |
1710 | if value[:1] == '.': | |
1711 | value = self._nametowidget(value) | |
1712 | dict[key] = value | |
1713 | return dict | |
1714 | info = pack_info | |
1715 | propagate = pack_propagate = Misc.pack_propagate | |
1716 | slaves = pack_slaves = Misc.pack_slaves | |
1717 | ||
1718 | class Place: | |
1719 | """Geometry manager Place. | |
1720 | ||
1721 | Base class to use the methods place_* in every widget.""" | |
1722 | def place_configure(self, cnf={}, **kw): | |
1723 | """Place a widget in the parent widget. Use as options: | |
1724 | in=master - master relative to which the widget is placed. | |
1725 | x=amount - locate anchor of this widget at position x of master | |
1726 | y=amount - locate anchor of this widget at position y of master | |
1727 | relx=amount - locate anchor of this widget between 0.0 and 1.0 | |
1728 | relative to width of master (1.0 is right edge) | |
1729 | rely=amount - locate anchor of this widget between 0.0 and 1.0 | |
1730 | relative to height of master (1.0 is bottom edge) | |
1731 | anchor=NSEW (or subset) - position anchor according to given direction | |
1732 | width=amount - width of this widget in pixel | |
1733 | height=amount - height of this widget in pixel | |
1734 | relwidth=amount - width of this widget between 0.0 and 1.0 | |
1735 | relative to width of master (1.0 is the same width | |
1736 | as the master) | |
1737 | relheight=amount - height of this widget between 0.0 and 1.0 | |
1738 | relative to height of master (1.0 is the same | |
1739 | height as the master) | |
1740 | bordermode="inside" or "outside" - whether to take border width of master widget | |
1741 | into account | |
1742 | """ | |
1743 | for k in ['in_']: | |
1744 | if kw.has_key(k): | |
1745 | kw[k[:-1]] = kw[k] | |
1746 | del kw[k] | |
1747 | self.tk.call( | |
1748 | ('place', 'configure', self._w) | |
1749 | + self._options(cnf, kw)) | |
1750 | place = configure = config = place_configure | |
1751 | def place_forget(self): | |
1752 | """Unmap this widget.""" | |
1753 | self.tk.call('place', 'forget', self._w) | |
1754 | forget = place_forget | |
1755 | def place_info(self): | |
1756 | """Return information about the placing options | |
1757 | for this widget.""" | |
1758 | words = self.tk.splitlist( | |
1759 | self.tk.call('place', 'info', self._w)) | |
1760 | dict = {} | |
1761 | for i in range(0, len(words), 2): | |
1762 | key = words[i][1:] | |
1763 | value = words[i+1] | |
1764 | if value[:1] == '.': | |
1765 | value = self._nametowidget(value) | |
1766 | dict[key] = value | |
1767 | return dict | |
1768 | info = place_info | |
1769 | slaves = place_slaves = Misc.place_slaves | |
1770 | ||
1771 | class Grid: | |
1772 | """Geometry manager Grid. | |
1773 | ||
1774 | Base class to use the methods grid_* in every widget.""" | |
1775 | # Thanks to Masazumi Yoshikawa (yosikawa@isi.edu) | |
1776 | def grid_configure(self, cnf={}, **kw): | |
1777 | """Position a widget in the parent widget in a grid. Use as options: | |
1778 | column=number - use cell identified with given column (starting with 0) | |
1779 | columnspan=number - this widget will span several columns | |
1780 | in=master - use master to contain this widget | |
1781 | ipadx=amount - add internal padding in x direction | |
1782 | ipady=amount - add internal padding in y direction | |
1783 | padx=amount - add padding in x direction | |
1784 | pady=amount - add padding in y direction | |
1785 | row=number - use cell identified with given row (starting with 0) | |
1786 | rowspan=number - this widget will span several rows | |
1787 | sticky=NSEW - if cell is larger on which sides will this | |
1788 | widget stick to the cell boundary | |
1789 | """ | |
1790 | self.tk.call( | |
1791 | ('grid', 'configure', self._w) | |
1792 | + self._options(cnf, kw)) | |
1793 | grid = configure = config = grid_configure | |
1794 | bbox = grid_bbox = Misc.grid_bbox | |
1795 | columnconfigure = grid_columnconfigure = Misc.grid_columnconfigure | |
1796 | def grid_forget(self): | |
1797 | """Unmap this widget.""" | |
1798 | self.tk.call('grid', 'forget', self._w) | |
1799 | forget = grid_forget | |
1800 | def grid_remove(self): | |
1801 | """Unmap this widget but remember the grid options.""" | |
1802 | self.tk.call('grid', 'remove', self._w) | |
1803 | def grid_info(self): | |
1804 | """Return information about the options | |
1805 | for positioning this widget in a grid.""" | |
1806 | words = self.tk.splitlist( | |
1807 | self.tk.call('grid', 'info', self._w)) | |
1808 | dict = {} | |
1809 | for i in range(0, len(words), 2): | |
1810 | key = words[i][1:] | |
1811 | value = words[i+1] | |
1812 | if value[:1] == '.': | |
1813 | value = self._nametowidget(value) | |
1814 | dict[key] = value | |
1815 | return dict | |
1816 | info = grid_info | |
1817 | location = grid_location = Misc.grid_location | |
1818 | propagate = grid_propagate = Misc.grid_propagate | |
1819 | rowconfigure = grid_rowconfigure = Misc.grid_rowconfigure | |
1820 | size = grid_size = Misc.grid_size | |
1821 | slaves = grid_slaves = Misc.grid_slaves | |
1822 | ||
1823 | class BaseWidget(Misc): | |
1824 | """Internal class.""" | |
1825 | def _setup(self, master, cnf): | |
1826 | """Internal function. Sets up information about children.""" | |
1827 | if _support_default_root: | |
1828 | global _default_root | |
1829 | if not master: | |
1830 | if not _default_root: | |
1831 | _default_root = Tk() | |
1832 | master = _default_root | |
1833 | self.master = master | |
1834 | self.tk = master.tk | |
1835 | name = None | |
1836 | if cnf.has_key('name'): | |
1837 | name = cnf['name'] | |
1838 | del cnf['name'] | |
1839 | if not name: | |
1840 | name = repr(id(self)) | |
1841 | self._name = name | |
1842 | if master._w=='.': | |
1843 | self._w = '.' + name | |
1844 | else: | |
1845 | self._w = master._w + '.' + name | |
1846 | self.children = {} | |
1847 | if self.master.children.has_key(self._name): | |
1848 | self.master.children[self._name].destroy() | |
1849 | self.master.children[self._name] = self | |
1850 | def __init__(self, master, widgetName, cnf={}, kw={}, extra=()): | |
1851 | """Construct a widget with the parent widget MASTER, a name WIDGETNAME | |
1852 | and appropriate options.""" | |
1853 | if kw: | |
1854 | cnf = _cnfmerge((cnf, kw)) | |
1855 | self.widgetName = widgetName | |
1856 | BaseWidget._setup(self, master, cnf) | |
1857 | classes = [] | |
1858 | for k in cnf.keys(): | |
1859 | if type(k) is ClassType: | |
1860 | classes.append((k, cnf[k])) | |
1861 | del cnf[k] | |
1862 | self.tk.call( | |
1863 | (widgetName, self._w) + extra + self._options(cnf)) | |
1864 | for k, v in classes: | |
1865 | k.configure(self, v) | |
1866 | def destroy(self): | |
1867 | """Destroy this and all descendants widgets.""" | |
1868 | for c in self.children.values(): c.destroy() | |
1869 | if self.master.children.has_key(self._name): | |
1870 | del self.master.children[self._name] | |
1871 | self.tk.call('destroy', self._w) | |
1872 | Misc.destroy(self) | |
1873 | def _do(self, name, args=()): | |
1874 | # XXX Obsolete -- better use self.tk.call directly! | |
1875 | return self.tk.call((self._w, name) + args) | |
1876 | ||
1877 | class Widget(BaseWidget, Pack, Place, Grid): | |
1878 | """Internal class. | |
1879 | ||
1880 | Base class for a widget which can be positioned with the geometry managers | |
1881 | Pack, Place or Grid.""" | |
1882 | pass | |
1883 | ||
1884 | class Toplevel(BaseWidget, Wm): | |
1885 | """Toplevel widget, e.g. for dialogs.""" | |
1886 | def __init__(self, master=None, cnf={}, **kw): | |
1887 | """Construct a toplevel widget with the parent MASTER. | |
1888 | ||
1889 | Valid resource names: background, bd, bg, borderwidth, class, | |
1890 | colormap, container, cursor, height, highlightbackground, | |
1891 | highlightcolor, highlightthickness, menu, relief, screen, takefocus, | |
1892 | use, visual, width.""" | |
1893 | if kw: | |
1894 | cnf = _cnfmerge((cnf, kw)) | |
1895 | extra = () | |
1896 | for wmkey in ['screen', 'class_', 'class', 'visual', | |
1897 | 'colormap']: | |
1898 | if cnf.has_key(wmkey): | |
1899 | val = cnf[wmkey] | |
1900 | # TBD: a hack needed because some keys | |
1901 | # are not valid as keyword arguments | |
1902 | if wmkey[-1] == '_': opt = '-'+wmkey[:-1] | |
1903 | else: opt = '-'+wmkey | |
1904 | extra = extra + (opt, val) | |
1905 | del cnf[wmkey] | |
1906 | BaseWidget.__init__(self, master, 'toplevel', cnf, {}, extra) | |
1907 | root = self._root() | |
1908 | self.iconname(root.iconname()) | |
1909 | self.title(root.title()) | |
1910 | self.protocol("WM_DELETE_WINDOW", self.destroy) | |
1911 | ||
1912 | class Button(Widget): | |
1913 | """Button widget.""" | |
1914 | def __init__(self, master=None, cnf={}, **kw): | |
1915 | """Construct a button widget with the parent MASTER. | |
1916 | ||
1917 | STANDARD OPTIONS | |
1918 | ||
1919 | activebackground, activeforeground, anchor, | |
1920 | background, bitmap, borderwidth, cursor, | |
1921 | disabledforeground, font, foreground | |
1922 | highlightbackground, highlightcolor, | |
1923 | highlightthickness, image, justify, | |
1924 | padx, pady, relief, repeatdelay, | |
1925 | repeatinterval, takefocus, text, | |
1926 | textvariable, underline, wraplength | |
1927 | ||
1928 | WIDGET-SPECIFIC OPTIONS | |
1929 | ||
1930 | command, compound, default, height, | |
1931 | overrelief, state, width | |
1932 | """ | |
1933 | Widget.__init__(self, master, 'button', cnf, kw) | |
1934 | ||
1935 | def tkButtonEnter(self, *dummy): | |
1936 | self.tk.call('tkButtonEnter', self._w) | |
1937 | ||
1938 | def tkButtonLeave(self, *dummy): | |
1939 | self.tk.call('tkButtonLeave', self._w) | |
1940 | ||
1941 | def tkButtonDown(self, *dummy): | |
1942 | self.tk.call('tkButtonDown', self._w) | |
1943 | ||
1944 | def tkButtonUp(self, *dummy): | |
1945 | self.tk.call('tkButtonUp', self._w) | |
1946 | ||
1947 | def tkButtonInvoke(self, *dummy): | |
1948 | self.tk.call('tkButtonInvoke', self._w) | |
1949 | ||
1950 | def flash(self): | |
1951 | """Flash the button. | |
1952 | ||
1953 | This is accomplished by redisplaying | |
1954 | the button several times, alternating between active and | |
1955 | normal colors. At the end of the flash the button is left | |
1956 | in the same normal/active state as when the command was | |
1957 | invoked. This command is ignored if the button's state is | |
1958 | disabled. | |
1959 | """ | |
1960 | self.tk.call(self._w, 'flash') | |
1961 | ||
1962 | def invoke(self): | |
1963 | """Invoke the command associated with the button. | |
1964 | ||
1965 | The return value is the return value from the command, | |
1966 | or an empty string if there is no command associated with | |
1967 | the button. This command is ignored if the button's state | |
1968 | is disabled. | |
1969 | """ | |
1970 | return self.tk.call(self._w, 'invoke') | |
1971 | ||
1972 | # Indices: | |
1973 | # XXX I don't like these -- take them away | |
1974 | def AtEnd(): | |
1975 | return 'end' | |
1976 | def AtInsert(*args): | |
1977 | s = 'insert' | |
1978 | for a in args: | |
1979 | if a: s = s + (' ' + a) | |
1980 | return s | |
1981 | def AtSelFirst(): | |
1982 | return 'sel.first' | |
1983 | def AtSelLast(): | |
1984 | return 'sel.last' | |
1985 | def At(x, y=None): | |
1986 | if y is None: | |
1987 | return '@%r' % (x,) | |
1988 | else: | |
1989 | return '@%r,%r' % (x, y) | |
1990 | ||
1991 | class Canvas(Widget): | |
1992 | """Canvas widget to display graphical elements like lines or text.""" | |
1993 | def __init__(self, master=None, cnf={}, **kw): | |
1994 | """Construct a canvas widget with the parent MASTER. | |
1995 | ||
1996 | Valid resource names: background, bd, bg, borderwidth, closeenough, | |
1997 | confine, cursor, height, highlightbackground, highlightcolor, | |
1998 | highlightthickness, insertbackground, insertborderwidth, | |
1999 | insertofftime, insertontime, insertwidth, offset, relief, | |
2000 | scrollregion, selectbackground, selectborderwidth, selectforeground, | |
2001 | state, takefocus, width, xscrollcommand, xscrollincrement, | |
2002 | yscrollcommand, yscrollincrement.""" | |
2003 | Widget.__init__(self, master, 'canvas', cnf, kw) | |
2004 | def addtag(self, *args): | |
2005 | """Internal function.""" | |
2006 | self.tk.call((self._w, 'addtag') + args) | |
2007 | def addtag_above(self, newtag, tagOrId): | |
2008 | """Add tag NEWTAG to all items above TAGORID.""" | |
2009 | self.addtag(newtag, 'above', tagOrId) | |
2010 | def addtag_all(self, newtag): | |
2011 | """Add tag NEWTAG to all items.""" | |
2012 | self.addtag(newtag, 'all') | |
2013 | def addtag_below(self, newtag, tagOrId): | |
2014 | """Add tag NEWTAG to all items below TAGORID.""" | |
2015 | self.addtag(newtag, 'below', tagOrId) | |
2016 | def addtag_closest(self, newtag, x, y, halo=None, start=None): | |
2017 | """Add tag NEWTAG to item which is closest to pixel at X, Y. | |
2018 | If several match take the top-most. | |
2019 | All items closer than HALO are considered overlapping (all are | |
2020 | closests). If START is specified the next below this tag is taken.""" | |
2021 | self.addtag(newtag, 'closest', x, y, halo, start) | |
2022 | def addtag_enclosed(self, newtag, x1, y1, x2, y2): | |
2023 | """Add tag NEWTAG to all items in the rectangle defined | |
2024 | by X1,Y1,X2,Y2.""" | |
2025 | self.addtag(newtag, 'enclosed', x1, y1, x2, y2) | |
2026 | def addtag_overlapping(self, newtag, x1, y1, x2, y2): | |
2027 | """Add tag NEWTAG to all items which overlap the rectangle | |
2028 | defined by X1,Y1,X2,Y2.""" | |
2029 | self.addtag(newtag, 'overlapping', x1, y1, x2, y2) | |
2030 | def addtag_withtag(self, newtag, tagOrId): | |
2031 | """Add tag NEWTAG to all items with TAGORID.""" | |
2032 | self.addtag(newtag, 'withtag', tagOrId) | |
2033 | def bbox(self, *args): | |
2034 | """Return a tuple of X1,Y1,X2,Y2 coordinates for a rectangle | |
2035 | which encloses all items with tags specified as arguments.""" | |
2036 | return self._getints( | |
2037 | self.tk.call((self._w, 'bbox') + args)) or None | |
2038 | def tag_unbind(self, tagOrId, sequence, funcid=None): | |
2039 | """Unbind for all items with TAGORID for event SEQUENCE the | |
2040 | function identified with FUNCID.""" | |
2041 | self.tk.call(self._w, 'bind', tagOrId, sequence, '') | |
2042 | if funcid: | |
2043 | self.deletecommand(funcid) | |
2044 | def tag_bind(self, tagOrId, sequence=None, func=None, add=None): | |
2045 | """Bind to all items with TAGORID at event SEQUENCE a call to function FUNC. | |
2046 | ||
2047 | An additional boolean parameter ADD specifies whether FUNC will be | |
2048 | called additionally to the other bound function or whether it will | |
2049 | replace the previous function. See bind for the return value.""" | |
2050 | return self._bind((self._w, 'bind', tagOrId), | |
2051 | sequence, func, add) | |
2052 | def canvasx(self, screenx, gridspacing=None): | |
2053 | """Return the canvas x coordinate of pixel position SCREENX rounded | |
2054 | to nearest multiple of GRIDSPACING units.""" | |
2055 | return getdouble(self.tk.call( | |
2056 | self._w, 'canvasx', screenx, gridspacing)) | |
2057 | def canvasy(self, screeny, gridspacing=None): | |
2058 | """Return the canvas y coordinate of pixel position SCREENY rounded | |
2059 | to nearest multiple of GRIDSPACING units.""" | |
2060 | return getdouble(self.tk.call( | |
2061 | self._w, 'canvasy', screeny, gridspacing)) | |
2062 | def coords(self, *args): | |
2063 | """Return a list of coordinates for the item given in ARGS.""" | |
2064 | # XXX Should use _flatten on args | |
2065 | return map(getdouble, | |
2066 | self.tk.splitlist( | |
2067 | self.tk.call((self._w, 'coords') + args))) | |
2068 | def _create(self, itemType, args, kw): # Args: (val, val, ..., cnf={}) | |
2069 | """Internal function.""" | |
2070 | args = _flatten(args) | |
2071 | cnf = args[-1] | |
2072 | if type(cnf) in (DictionaryType, TupleType): | |
2073 | args = args[:-1] | |
2074 | else: | |
2075 | cnf = {} | |
2076 | return getint(self.tk.call( | |
2077 | self._w, 'create', itemType, | |
2078 | *(args + self._options(cnf, kw)))) | |
2079 | def create_arc(self, *args, **kw): | |
2080 | """Create arc shaped region with coordinates x1,y1,x2,y2.""" | |
2081 | return self._create('arc', args, kw) | |
2082 | def create_bitmap(self, *args, **kw): | |
2083 | """Create bitmap with coordinates x1,y1.""" | |
2084 | return self._create('bitmap', args, kw) | |
2085 | def create_image(self, *args, **kw): | |
2086 | """Create image item with coordinates x1,y1.""" | |
2087 | return self._create('image', args, kw) | |
2088 | def create_line(self, *args, **kw): | |
2089 | """Create line with coordinates x1,y1,...,xn,yn.""" | |
2090 | return self._create('line', args, kw) | |
2091 | def create_oval(self, *args, **kw): | |
2092 | """Create oval with coordinates x1,y1,x2,y2.""" | |
2093 | return self._create('oval', args, kw) | |
2094 | def create_polygon(self, *args, **kw): | |
2095 | """Create polygon with coordinates x1,y1,...,xn,yn.""" | |
2096 | return self._create('polygon', args, kw) | |
2097 | def create_rectangle(self, *args, **kw): | |
2098 | """Create rectangle with coordinates x1,y1,x2,y2.""" | |
2099 | return self._create('rectangle', args, kw) | |
2100 | def create_text(self, *args, **kw): | |
2101 | """Create text with coordinates x1,y1.""" | |
2102 | return self._create('text', args, kw) | |
2103 | def create_window(self, *args, **kw): | |
2104 | """Create window with coordinates x1,y1,x2,y2.""" | |
2105 | return self._create('window', args, kw) | |
2106 | def dchars(self, *args): | |
2107 | """Delete characters of text items identified by tag or id in ARGS (possibly | |
2108 | several times) from FIRST to LAST character (including).""" | |
2109 | self.tk.call((self._w, 'dchars') + args) | |
2110 | def delete(self, *args): | |
2111 | """Delete items identified by all tag or ids contained in ARGS.""" | |
2112 | self.tk.call((self._w, 'delete') + args) | |
2113 | def dtag(self, *args): | |
2114 | """Delete tag or id given as last arguments in ARGS from items | |
2115 | identified by first argument in ARGS.""" | |
2116 | self.tk.call((self._w, 'dtag') + args) | |
2117 | def find(self, *args): | |
2118 | """Internal function.""" | |
2119 | return self._getints( | |
2120 | self.tk.call((self._w, 'find') + args)) or () | |
2121 | def find_above(self, tagOrId): | |
2122 | """Return items above TAGORID.""" | |
2123 | return self.find('above', tagOrId) | |
2124 | def find_all(self): | |
2125 | """Return all items.""" | |
2126 | return self.find('all') | |
2127 | def find_below(self, tagOrId): | |
2128 | """Return all items below TAGORID.""" | |
2129 | return self.find('below', tagOrId) | |
2130 | def find_closest(self, x, y, halo=None, start=None): | |
2131 | """Return item which is closest to pixel at X, Y. | |
2132 | If several match take the top-most. | |
2133 | All items closer than HALO are considered overlapping (all are | |
2134 | closests). If START is specified the next below this tag is taken.""" | |
2135 | return self.find('closest', x, y, halo, start) | |
2136 | def find_enclosed(self, x1, y1, x2, y2): | |
2137 | """Return all items in rectangle defined | |
2138 | by X1,Y1,X2,Y2.""" | |
2139 | return self.find('enclosed', x1, y1, x2, y2) | |
2140 | def find_overlapping(self, x1, y1, x2, y2): | |
2141 | """Return all items which overlap the rectangle | |
2142 | defined by X1,Y1,X2,Y2.""" | |
2143 | return self.find('overlapping', x1, y1, x2, y2) | |
2144 | def find_withtag(self, tagOrId): | |
2145 | """Return all items with TAGORID.""" | |
2146 | return self.find('withtag', tagOrId) | |
2147 | def focus(self, *args): | |
2148 | """Set focus to the first item specified in ARGS.""" | |
2149 | return self.tk.call((self._w, 'focus') + args) | |
2150 | def gettags(self, *args): | |
2151 | """Return tags associated with the first item specified in ARGS.""" | |
2152 | return self.tk.splitlist( | |
2153 | self.tk.call((self._w, 'gettags') + args)) | |
2154 | def icursor(self, *args): | |
2155 | """Set cursor at position POS in the item identified by TAGORID. | |
2156 | In ARGS TAGORID must be first.""" | |
2157 | self.tk.call((self._w, 'icursor') + args) | |
2158 | def index(self, *args): | |
2159 | """Return position of cursor as integer in item specified in ARGS.""" | |
2160 | return getint(self.tk.call((self._w, 'index') + args)) | |
2161 | def insert(self, *args): | |
2162 | """Insert TEXT in item TAGORID at position POS. ARGS must | |
2163 | be TAGORID POS TEXT.""" | |
2164 | self.tk.call((self._w, 'insert') + args) | |
2165 | def itemcget(self, tagOrId, option): | |
2166 | """Return the resource value for an OPTION for item TAGORID.""" | |
2167 | return self.tk.call( | |
2168 | (self._w, 'itemcget') + (tagOrId, '-'+option)) | |
2169 | def itemconfigure(self, tagOrId, cnf=None, **kw): | |
2170 | """Configure resources of an item TAGORID. | |
2171 | ||
2172 | The values for resources are specified as keyword | |
2173 | arguments. To get an overview about | |
2174 | the allowed keyword arguments call the method without arguments. | |
2175 | """ | |
2176 | return self._configure(('itemconfigure', tagOrId), cnf, kw) | |
2177 | itemconfig = itemconfigure | |
2178 | # lower, tkraise/lift hide Misc.lower, Misc.tkraise/lift, | |
2179 | # so the preferred name for them is tag_lower, tag_raise | |
2180 | # (similar to tag_bind, and similar to the Text widget); | |
2181 | # unfortunately can't delete the old ones yet (maybe in 1.6) | |
2182 | def tag_lower(self, *args): | |
2183 | """Lower an item TAGORID given in ARGS | |
2184 | (optional below another item).""" | |
2185 | self.tk.call((self._w, 'lower') + args) | |
2186 | lower = tag_lower | |
2187 | def move(self, *args): | |
2188 | """Move an item TAGORID given in ARGS.""" | |
2189 | self.tk.call((self._w, 'move') + args) | |
2190 | def postscript(self, cnf={}, **kw): | |
2191 | """Print the contents of the canvas to a postscript | |
2192 | file. Valid options: colormap, colormode, file, fontmap, | |
2193 | height, pageanchor, pageheight, pagewidth, pagex, pagey, | |
2194 | rotate, witdh, x, y.""" | |
2195 | return self.tk.call((self._w, 'postscript') + | |
2196 | self._options(cnf, kw)) | |
2197 | def tag_raise(self, *args): | |
2198 | """Raise an item TAGORID given in ARGS | |
2199 | (optional above another item).""" | |
2200 | self.tk.call((self._w, 'raise') + args) | |
2201 | lift = tkraise = tag_raise | |
2202 | def scale(self, *args): | |
2203 | """Scale item TAGORID with XORIGIN, YORIGIN, XSCALE, YSCALE.""" | |
2204 | self.tk.call((self._w, 'scale') + args) | |
2205 | def scan_mark(self, x, y): | |
2206 | """Remember the current X, Y coordinates.""" | |
2207 | self.tk.call(self._w, 'scan', 'mark', x, y) | |
2208 | def scan_dragto(self, x, y, gain=10): | |
2209 | """Adjust the view of the canvas to GAIN times the | |
2210 | difference between X and Y and the coordinates given in | |
2211 | scan_mark.""" | |
2212 | self.tk.call(self._w, 'scan', 'dragto', x, y, gain) | |
2213 | def select_adjust(self, tagOrId, index): | |
2214 | """Adjust the end of the selection near the cursor of an item TAGORID to index.""" | |
2215 | self.tk.call(self._w, 'select', 'adjust', tagOrId, index) | |
2216 | def select_clear(self): | |
2217 | """Clear the selection if it is in this widget.""" | |
2218 | self.tk.call(self._w, 'select', 'clear') | |
2219 | def select_from(self, tagOrId, index): | |
2220 | """Set the fixed end of a selection in item TAGORID to INDEX.""" | |
2221 | self.tk.call(self._w, 'select', 'from', tagOrId, index) | |
2222 | def select_item(self): | |
2223 | """Return the item which has the selection.""" | |
2224 | return self.tk.call(self._w, 'select', 'item') or None | |
2225 | def select_to(self, tagOrId, index): | |
2226 | """Set the variable end of a selection in item TAGORID to INDEX.""" | |
2227 | self.tk.call(self._w, 'select', 'to', tagOrId, index) | |
2228 | def type(self, tagOrId): | |
2229 | """Return the type of the item TAGORID.""" | |
2230 | return self.tk.call(self._w, 'type', tagOrId) or None | |
2231 | def xview(self, *args): | |
2232 | """Query and change horizontal position of the view.""" | |
2233 | if not args: | |
2234 | return self._getdoubles(self.tk.call(self._w, 'xview')) | |
2235 | self.tk.call((self._w, 'xview') + args) | |
2236 | def xview_moveto(self, fraction): | |
2237 | """Adjusts the view in the window so that FRACTION of the | |
2238 | total width of the canvas is off-screen to the left.""" | |
2239 | self.tk.call(self._w, 'xview', 'moveto', fraction) | |
2240 | def xview_scroll(self, number, what): | |
2241 | """Shift the x-view according to NUMBER which is measured in "units" or "pages" (WHAT).""" | |
2242 | self.tk.call(self._w, 'xview', 'scroll', number, what) | |
2243 | def yview(self, *args): | |
2244 | """Query and change vertical position of the view.""" | |
2245 | if not args: | |
2246 | return self._getdoubles(self.tk.call(self._w, 'yview')) | |
2247 | self.tk.call((self._w, 'yview') + args) | |
2248 | def yview_moveto(self, fraction): | |
2249 | """Adjusts the view in the window so that FRACTION of the | |
2250 | total height of the canvas is off-screen to the top.""" | |
2251 | self.tk.call(self._w, 'yview', 'moveto', fraction) | |
2252 | def yview_scroll(self, number, what): | |
2253 | """Shift the y-view according to NUMBER which is measured in "units" or "pages" (WHAT).""" | |
2254 | self.tk.call(self._w, 'yview', 'scroll', number, what) | |
2255 | ||
2256 | class Checkbutton(Widget): | |
2257 | """Checkbutton widget which is either in on- or off-state.""" | |
2258 | def __init__(self, master=None, cnf={}, **kw): | |
2259 | """Construct a checkbutton widget with the parent MASTER. | |
2260 | ||
2261 | Valid resource names: activebackground, activeforeground, anchor, | |
2262 | background, bd, bg, bitmap, borderwidth, command, cursor, | |
2263 | disabledforeground, fg, font, foreground, height, | |
2264 | highlightbackground, highlightcolor, highlightthickness, image, | |
2265 | indicatoron, justify, offvalue, onvalue, padx, pady, relief, | |
2266 | selectcolor, selectimage, state, takefocus, text, textvariable, | |
2267 | underline, variable, width, wraplength.""" | |
2268 | Widget.__init__(self, master, 'checkbutton', cnf, kw) | |
2269 | def deselect(self): | |
2270 | """Put the button in off-state.""" | |
2271 | self.tk.call(self._w, 'deselect') | |
2272 | def flash(self): | |
2273 | """Flash the button.""" | |
2274 | self.tk.call(self._w, 'flash') | |
2275 | def invoke(self): | |
2276 | """Toggle the button and invoke a command if given as resource.""" | |
2277 | return self.tk.call(self._w, 'invoke') | |
2278 | def select(self): | |
2279 | """Put the button in on-state.""" | |
2280 | self.tk.call(self._w, 'select') | |
2281 | def toggle(self): | |
2282 | """Toggle the button.""" | |
2283 | self.tk.call(self._w, 'toggle') | |
2284 | ||
2285 | class Entry(Widget): | |
2286 | """Entry widget which allows to display simple text.""" | |
2287 | def __init__(self, master=None, cnf={}, **kw): | |
2288 | """Construct an entry widget with the parent MASTER. | |
2289 | ||
2290 | Valid resource names: background, bd, bg, borderwidth, cursor, | |
2291 | exportselection, fg, font, foreground, highlightbackground, | |
2292 | highlightcolor, highlightthickness, insertbackground, | |
2293 | insertborderwidth, insertofftime, insertontime, insertwidth, | |
2294 | invalidcommand, invcmd, justify, relief, selectbackground, | |
2295 | selectborderwidth, selectforeground, show, state, takefocus, | |
2296 | textvariable, validate, validatecommand, vcmd, width, | |
2297 | xscrollcommand.""" | |
2298 | Widget.__init__(self, master, 'entry', cnf, kw) | |
2299 | def delete(self, first, last=None): | |
2300 | """Delete text from FIRST to LAST (not included).""" | |
2301 | self.tk.call(self._w, 'delete', first, last) | |
2302 | def get(self): | |
2303 | """Return the text.""" | |
2304 | return self.tk.call(self._w, 'get') | |
2305 | def icursor(self, index): | |
2306 | """Insert cursor at INDEX.""" | |
2307 | self.tk.call(self._w, 'icursor', index) | |
2308 | def index(self, index): | |
2309 | """Return position of cursor.""" | |
2310 | return getint(self.tk.call( | |
2311 | self._w, 'index', index)) | |
2312 | def insert(self, index, string): | |
2313 | """Insert STRING at INDEX.""" | |
2314 | self.tk.call(self._w, 'insert', index, string) | |
2315 | def scan_mark(self, x): | |
2316 | """Remember the current X, Y coordinates.""" | |
2317 | self.tk.call(self._w, 'scan', 'mark', x) | |
2318 | def scan_dragto(self, x): | |
2319 | """Adjust the view of the canvas to 10 times the | |
2320 | difference between X and Y and the coordinates given in | |
2321 | scan_mark.""" | |
2322 | self.tk.call(self._w, 'scan', 'dragto', x) | |
2323 | def selection_adjust(self, index): | |
2324 | """Adjust the end of the selection near the cursor to INDEX.""" | |
2325 | self.tk.call(self._w, 'selection', 'adjust', index) | |
2326 | select_adjust = selection_adjust | |
2327 | def selection_clear(self): | |
2328 | """Clear the selection if it is in this widget.""" | |
2329 | self.tk.call(self._w, 'selection', 'clear') | |
2330 | select_clear = selection_clear | |
2331 | def selection_from(self, index): | |
2332 | """Set the fixed end of a selection to INDEX.""" | |
2333 | self.tk.call(self._w, 'selection', 'from', index) | |
2334 | select_from = selection_from | |
2335 | def selection_present(self): | |
2336 | """Return whether the widget has the selection.""" | |
2337 | return self.tk.getboolean( | |
2338 | self.tk.call(self._w, 'selection', 'present')) | |
2339 | select_present = selection_present | |
2340 | def selection_range(self, start, end): | |
2341 | """Set the selection from START to END (not included).""" | |
2342 | self.tk.call(self._w, 'selection', 'range', start, end) | |
2343 | select_range = selection_range | |
2344 | def selection_to(self, index): | |
2345 | """Set the variable end of a selection to INDEX.""" | |
2346 | self.tk.call(self._w, 'selection', 'to', index) | |
2347 | select_to = selection_to | |
2348 | def xview(self, index): | |
2349 | """Query and change horizontal position of the view.""" | |
2350 | self.tk.call(self._w, 'xview', index) | |
2351 | def xview_moveto(self, fraction): | |
2352 | """Adjust the view in the window so that FRACTION of the | |
2353 | total width of the entry is off-screen to the left.""" | |
2354 | self.tk.call(self._w, 'xview', 'moveto', fraction) | |
2355 | def xview_scroll(self, number, what): | |
2356 | """Shift the x-view according to NUMBER which is measured in "units" or "pages" (WHAT).""" | |
2357 | self.tk.call(self._w, 'xview', 'scroll', number, what) | |
2358 | ||
2359 | class Frame(Widget): | |
2360 | """Frame widget which may contain other widgets and can have a 3D border.""" | |
2361 | def __init__(self, master=None, cnf={}, **kw): | |
2362 | """Construct a frame widget with the parent MASTER. | |
2363 | ||
2364 | Valid resource names: background, bd, bg, borderwidth, class, | |
2365 | colormap, container, cursor, height, highlightbackground, | |
2366 | highlightcolor, highlightthickness, relief, takefocus, visual, width.""" | |
2367 | cnf = _cnfmerge((cnf, kw)) | |
2368 | extra = () | |
2369 | if cnf.has_key('class_'): | |
2370 | extra = ('-class', cnf['class_']) | |
2371 | del cnf['class_'] | |
2372 | elif cnf.has_key('class'): | |
2373 | extra = ('-class', cnf['class']) | |
2374 | del cnf['class'] | |
2375 | Widget.__init__(self, master, 'frame', cnf, {}, extra) | |
2376 | ||
2377 | class Label(Widget): | |
2378 | """Label widget which can display text and bitmaps.""" | |
2379 | def __init__(self, master=None, cnf={}, **kw): | |
2380 | """Construct a label widget with the parent MASTER. | |
2381 | ||
2382 | STANDARD OPTIONS | |
2383 | ||
2384 | activebackground, activeforeground, anchor, | |
2385 | background, bitmap, borderwidth, cursor, | |
2386 | disabledforeground, font, foreground, | |
2387 | highlightbackground, highlightcolor, | |
2388 | highlightthickness, image, justify, | |
2389 | padx, pady, relief, takefocus, text, | |
2390 | textvariable, underline, wraplength | |
2391 | ||
2392 | WIDGET-SPECIFIC OPTIONS | |
2393 | ||
2394 | height, state, width | |
2395 | ||
2396 | """ | |
2397 | Widget.__init__(self, master, 'label', cnf, kw) | |
2398 | ||
2399 | class Listbox(Widget): | |
2400 | """Listbox widget which can display a list of strings.""" | |
2401 | def __init__(self, master=None, cnf={}, **kw): | |
2402 | """Construct a listbox widget with the parent MASTER. | |
2403 | ||
2404 | Valid resource names: background, bd, bg, borderwidth, cursor, | |
2405 | exportselection, fg, font, foreground, height, highlightbackground, | |
2406 | highlightcolor, highlightthickness, relief, selectbackground, | |
2407 | selectborderwidth, selectforeground, selectmode, setgrid, takefocus, | |
2408 | width, xscrollcommand, yscrollcommand, listvariable.""" | |
2409 | Widget.__init__(self, master, 'listbox', cnf, kw) | |
2410 | def activate(self, index): | |
2411 | """Activate item identified by INDEX.""" | |
2412 | self.tk.call(self._w, 'activate', index) | |
2413 | def bbox(self, *args): | |
2414 | """Return a tuple of X1,Y1,X2,Y2 coordinates for a rectangle | |
2415 | which encloses the item identified by index in ARGS.""" | |
2416 | return self._getints( | |
2417 | self.tk.call((self._w, 'bbox') + args)) or None | |
2418 | def curselection(self): | |
2419 | """Return list of indices of currently selected item.""" | |
2420 | # XXX Ought to apply self._getints()... | |
2421 | return self.tk.splitlist(self.tk.call( | |
2422 | self._w, 'curselection')) | |
2423 | def delete(self, first, last=None): | |
2424 | """Delete items from FIRST to LAST (not included).""" | |
2425 | self.tk.call(self._w, 'delete', first, last) | |
2426 | def get(self, first, last=None): | |
2427 | """Get list of items from FIRST to LAST (not included).""" | |
2428 | if last: | |
2429 | return self.tk.splitlist(self.tk.call( | |
2430 | self._w, 'get', first, last)) | |
2431 | else: | |
2432 | return self.tk.call(self._w, 'get', first) | |
2433 | def index(self, index): | |
2434 | """Return index of item identified with INDEX.""" | |
2435 | i = self.tk.call(self._w, 'index', index) | |
2436 | if i == 'none': return None | |
2437 | return getint(i) | |
2438 | def insert(self, index, *elements): | |
2439 | """Insert ELEMENTS at INDEX.""" | |
2440 | self.tk.call((self._w, 'insert', index) + elements) | |
2441 | def nearest(self, y): | |
2442 | """Get index of item which is nearest to y coordinate Y.""" | |
2443 | return getint(self.tk.call( | |
2444 | self._w, 'nearest', y)) | |
2445 | def scan_mark(self, x, y): | |
2446 | """Remember the current X, Y coordinates.""" | |
2447 | self.tk.call(self._w, 'scan', 'mark', x, y) | |
2448 | def scan_dragto(self, x, y): | |
2449 | """Adjust the view of the listbox to 10 times the | |
2450 | difference between X and Y and the coordinates given in | |
2451 | scan_mark.""" | |
2452 | self.tk.call(self._w, 'scan', 'dragto', x, y) | |
2453 | def see(self, index): | |
2454 | """Scroll such that INDEX is visible.""" | |
2455 | self.tk.call(self._w, 'see', index) | |
2456 | def selection_anchor(self, index): | |
2457 | """Set the fixed end oft the selection to INDEX.""" | |
2458 | self.tk.call(self._w, 'selection', 'anchor', index) | |
2459 | select_anchor = selection_anchor | |
2460 | def selection_clear(self, first, last=None): | |
2461 | """Clear the selection from FIRST to LAST (not included).""" | |
2462 | self.tk.call(self._w, | |
2463 | 'selection', 'clear', first, last) | |
2464 | select_clear = selection_clear | |
2465 | def selection_includes(self, index): | |
2466 | """Return 1 if INDEX is part of the selection.""" | |
2467 | return self.tk.getboolean(self.tk.call( | |
2468 | self._w, 'selection', 'includes', index)) | |
2469 | select_includes = selection_includes | |
2470 | def selection_set(self, first, last=None): | |
2471 | """Set the selection from FIRST to LAST (not included) without | |
2472 | changing the currently selected elements.""" | |
2473 | self.tk.call(self._w, 'selection', 'set', first, last) | |
2474 | select_set = selection_set | |
2475 | def size(self): | |
2476 | """Return the number of elements in the listbox.""" | |
2477 | return getint(self.tk.call(self._w, 'size')) | |
2478 | def xview(self, *what): | |
2479 | """Query and change horizontal position of the view.""" | |
2480 | if not what: | |
2481 | return self._getdoubles(self.tk.call(self._w, 'xview')) | |
2482 | self.tk.call((self._w, 'xview') + what) | |
2483 | def xview_moveto(self, fraction): | |
2484 | """Adjust the view in the window so that FRACTION of the | |
2485 | total width of the entry is off-screen to the left.""" | |
2486 | self.tk.call(self._w, 'xview', 'moveto', fraction) | |
2487 | def xview_scroll(self, number, what): | |
2488 | """Shift the x-view according to NUMBER which is measured in "units" or "pages" (WHAT).""" | |
2489 | self.tk.call(self._w, 'xview', 'scroll', number, what) | |
2490 | def yview(self, *what): | |
2491 | """Query and change vertical position of the view.""" | |
2492 | if not what: | |
2493 | return self._getdoubles(self.tk.call(self._w, 'yview')) | |
2494 | self.tk.call((self._w, 'yview') + what) | |
2495 | def yview_moveto(self, fraction): | |
2496 | """Adjust the view in the window so that FRACTION of the | |
2497 | total width of the entry is off-screen to the top.""" | |
2498 | self.tk.call(self._w, 'yview', 'moveto', fraction) | |
2499 | def yview_scroll(self, number, what): | |
2500 | """Shift the y-view according to NUMBER which is measured in "units" or "pages" (WHAT).""" | |
2501 | self.tk.call(self._w, 'yview', 'scroll', number, what) | |
2502 | def itemcget(self, index, option): | |
2503 | """Return the resource value for an ITEM and an OPTION.""" | |
2504 | return self.tk.call( | |
2505 | (self._w, 'itemcget') + (index, '-'+option)) | |
2506 | def itemconfigure(self, index, cnf=None, **kw): | |
2507 | """Configure resources of an ITEM. | |
2508 | ||
2509 | The values for resources are specified as keyword arguments. | |
2510 | To get an overview about the allowed keyword arguments | |
2511 | call the method without arguments. | |
2512 | Valid resource names: background, bg, foreground, fg, | |
2513 | selectbackground, selectforeground.""" | |
2514 | return self._configure(('itemconfigure', index), cnf, kw) | |
2515 | itemconfig = itemconfigure | |
2516 | ||
2517 | class Menu(Widget): | |
2518 | """Menu widget which allows to display menu bars, pull-down menus and pop-up menus.""" | |
2519 | def __init__(self, master=None, cnf={}, **kw): | |
2520 | """Construct menu widget with the parent MASTER. | |
2521 | ||
2522 | Valid resource names: activebackground, activeborderwidth, | |
2523 | activeforeground, background, bd, bg, borderwidth, cursor, | |
2524 | disabledforeground, fg, font, foreground, postcommand, relief, | |
2525 | selectcolor, takefocus, tearoff, tearoffcommand, title, type.""" | |
2526 | Widget.__init__(self, master, 'menu', cnf, kw) | |
2527 | def tk_bindForTraversal(self): | |
2528 | pass # obsolete since Tk 4.0 | |
2529 | def tk_mbPost(self): | |
2530 | self.tk.call('tk_mbPost', self._w) | |
2531 | def tk_mbUnpost(self): | |
2532 | self.tk.call('tk_mbUnpost') | |
2533 | def tk_traverseToMenu(self, char): | |
2534 | self.tk.call('tk_traverseToMenu', self._w, char) | |
2535 | def tk_traverseWithinMenu(self, char): | |
2536 | self.tk.call('tk_traverseWithinMenu', self._w, char) | |
2537 | def tk_getMenuButtons(self): | |
2538 | return self.tk.call('tk_getMenuButtons', self._w) | |
2539 | def tk_nextMenu(self, count): | |
2540 | self.tk.call('tk_nextMenu', count) | |
2541 | def tk_nextMenuEntry(self, count): | |
2542 | self.tk.call('tk_nextMenuEntry', count) | |
2543 | def tk_invokeMenu(self): | |
2544 | self.tk.call('tk_invokeMenu', self._w) | |
2545 | def tk_firstMenu(self): | |
2546 | self.tk.call('tk_firstMenu', self._w) | |
2547 | def tk_mbButtonDown(self): | |
2548 | self.tk.call('tk_mbButtonDown', self._w) | |
2549 | def tk_popup(self, x, y, entry=""): | |
2550 | """Post the menu at position X,Y with entry ENTRY.""" | |
2551 | self.tk.call('tk_popup', self._w, x, y, entry) | |
2552 | def activate(self, index): | |
2553 | """Activate entry at INDEX.""" | |
2554 | self.tk.call(self._w, 'activate', index) | |
2555 | def add(self, itemType, cnf={}, **kw): | |
2556 | """Internal function.""" | |
2557 | self.tk.call((self._w, 'add', itemType) + | |
2558 | self._options(cnf, kw)) | |
2559 | def add_cascade(self, cnf={}, **kw): | |
2560 | """Add hierarchical menu item.""" | |
2561 | self.add('cascade', cnf or kw) | |
2562 | def add_checkbutton(self, cnf={}, **kw): | |
2563 | """Add checkbutton menu item.""" | |
2564 | self.add('checkbutton', cnf or kw) | |
2565 | def add_command(self, cnf={}, **kw): | |
2566 | """Add command menu item.""" | |
2567 | self.add('command', cnf or kw) | |
2568 | def add_radiobutton(self, cnf={}, **kw): | |
2569 | """Addd radio menu item.""" | |
2570 | self.add('radiobutton', cnf or kw) | |
2571 | def add_separator(self, cnf={}, **kw): | |
2572 | """Add separator.""" | |
2573 | self.add('separator', cnf or kw) | |
2574 | def insert(self, index, itemType, cnf={}, **kw): | |
2575 | """Internal function.""" | |
2576 | self.tk.call((self._w, 'insert', index, itemType) + | |
2577 | self._options(cnf, kw)) | |
2578 | def insert_cascade(self, index, cnf={}, **kw): | |
2579 | """Add hierarchical menu item at INDEX.""" | |
2580 | self.insert(index, 'cascade', cnf or kw) | |
2581 | def insert_checkbutton(self, index, cnf={}, **kw): | |
2582 | """Add checkbutton menu item at INDEX.""" | |
2583 | self.insert(index, 'checkbutton', cnf or kw) | |
2584 | def insert_command(self, index, cnf={}, **kw): | |
2585 | """Add command menu item at INDEX.""" | |
2586 | self.insert(index, 'command', cnf or kw) | |
2587 | def insert_radiobutton(self, index, cnf={}, **kw): | |
2588 | """Addd radio menu item at INDEX.""" | |
2589 | self.insert(index, 'radiobutton', cnf or kw) | |
2590 | def insert_separator(self, index, cnf={}, **kw): | |
2591 | """Add separator at INDEX.""" | |
2592 | self.insert(index, 'separator', cnf or kw) | |
2593 | def delete(self, index1, index2=None): | |
2594 | """Delete menu items between INDEX1 and INDEX2 (not included).""" | |
2595 | self.tk.call(self._w, 'delete', index1, index2) | |
2596 | def entrycget(self, index, option): | |
2597 | """Return the resource value of an menu item for OPTION at INDEX.""" | |
2598 | return self.tk.call(self._w, 'entrycget', index, '-' + option) | |
2599 | def entryconfigure(self, index, cnf=None, **kw): | |
2600 | """Configure a menu item at INDEX.""" | |
2601 | return self._configure(('entryconfigure', index), cnf, kw) | |
2602 | entryconfig = entryconfigure | |
2603 | def index(self, index): | |
2604 | """Return the index of a menu item identified by INDEX.""" | |
2605 | i = self.tk.call(self._w, 'index', index) | |
2606 | if i == 'none': return None | |
2607 | return getint(i) | |
2608 | def invoke(self, index): | |
2609 | """Invoke a menu item identified by INDEX and execute | |
2610 | the associated command.""" | |
2611 | return self.tk.call(self._w, 'invoke', index) | |
2612 | def post(self, x, y): | |
2613 | """Display a menu at position X,Y.""" | |
2614 | self.tk.call(self._w, 'post', x, y) | |
2615 | def type(self, index): | |
2616 | """Return the type of the menu item at INDEX.""" | |
2617 | return self.tk.call(self._w, 'type', index) | |
2618 | def unpost(self): | |
2619 | """Unmap a menu.""" | |
2620 | self.tk.call(self._w, 'unpost') | |
2621 | def yposition(self, index): | |
2622 | """Return the y-position of the topmost pixel of the menu item at INDEX.""" | |
2623 | return getint(self.tk.call( | |
2624 | self._w, 'yposition', index)) | |
2625 | ||
2626 | class Menubutton(Widget): | |
2627 | """Menubutton widget, obsolete since Tk8.0.""" | |
2628 | def __init__(self, master=None, cnf={}, **kw): | |
2629 | Widget.__init__(self, master, 'menubutton', cnf, kw) | |
2630 | ||
2631 | class Message(Widget): | |
2632 | """Message widget to display multiline text. Obsolete since Label does it too.""" | |
2633 | def __init__(self, master=None, cnf={}, **kw): | |
2634 | Widget.__init__(self, master, 'message', cnf, kw) | |
2635 | ||
2636 | class Radiobutton(Widget): | |
2637 | """Radiobutton widget which shows only one of several buttons in on-state.""" | |
2638 | def __init__(self, master=None, cnf={}, **kw): | |
2639 | """Construct a radiobutton widget with the parent MASTER. | |
2640 | ||
2641 | Valid resource names: activebackground, activeforeground, anchor, | |
2642 | background, bd, bg, bitmap, borderwidth, command, cursor, | |
2643 | disabledforeground, fg, font, foreground, height, | |
2644 | highlightbackground, highlightcolor, highlightthickness, image, | |
2645 | indicatoron, justify, padx, pady, relief, selectcolor, selectimage, | |
2646 | state, takefocus, text, textvariable, underline, value, variable, | |
2647 | width, wraplength.""" | |
2648 | Widget.__init__(self, master, 'radiobutton', cnf, kw) | |
2649 | def deselect(self): | |
2650 | """Put the button in off-state.""" | |
2651 | ||
2652 | self.tk.call(self._w, 'deselect') | |
2653 | def flash(self): | |
2654 | """Flash the button.""" | |
2655 | self.tk.call(self._w, 'flash') | |
2656 | def invoke(self): | |
2657 | """Toggle the button and invoke a command if given as resource.""" | |
2658 | return self.tk.call(self._w, 'invoke') | |
2659 | def select(self): | |
2660 | """Put the button in on-state.""" | |
2661 | self.tk.call(self._w, 'select') | |
2662 | ||
2663 | class Scale(Widget): | |
2664 | """Scale widget which can display a numerical scale.""" | |
2665 | def __init__(self, master=None, cnf={}, **kw): | |
2666 | """Construct a scale widget with the parent MASTER. | |
2667 | ||
2668 | Valid resource names: activebackground, background, bigincrement, bd, | |
2669 | bg, borderwidth, command, cursor, digits, fg, font, foreground, from, | |
2670 | highlightbackground, highlightcolor, highlightthickness, label, | |
2671 | length, orient, relief, repeatdelay, repeatinterval, resolution, | |
2672 | showvalue, sliderlength, sliderrelief, state, takefocus, | |
2673 | tickinterval, to, troughcolor, variable, width.""" | |
2674 | Widget.__init__(self, master, 'scale', cnf, kw) | |
2675 | def get(self): | |
2676 | """Get the current value as integer or float.""" | |
2677 | value = self.tk.call(self._w, 'get') | |
2678 | try: | |
2679 | return getint(value) | |
2680 | except ValueError: | |
2681 | return getdouble(value) | |
2682 | def set(self, value): | |
2683 | """Set the value to VALUE.""" | |
2684 | self.tk.call(self._w, 'set', value) | |
2685 | def coords(self, value=None): | |
2686 | """Return a tuple (X,Y) of the point along the centerline of the | |
2687 | trough that corresponds to VALUE or the current value if None is | |
2688 | given.""" | |
2689 | ||
2690 | return self._getints(self.tk.call(self._w, 'coords', value)) | |
2691 | def identify(self, x, y): | |
2692 | """Return where the point X,Y lies. Valid return values are "slider", | |
2693 | "though1" and "though2".""" | |
2694 | return self.tk.call(self._w, 'identify', x, y) | |
2695 | ||
2696 | class Scrollbar(Widget): | |
2697 | """Scrollbar widget which displays a slider at a certain position.""" | |
2698 | def __init__(self, master=None, cnf={}, **kw): | |
2699 | """Construct a scrollbar widget with the parent MASTER. | |
2700 | ||
2701 | Valid resource names: activebackground, activerelief, | |
2702 | background, bd, bg, borderwidth, command, cursor, | |
2703 | elementborderwidth, highlightbackground, | |
2704 | highlightcolor, highlightthickness, jump, orient, | |
2705 | relief, repeatdelay, repeatinterval, takefocus, | |
2706 | troughcolor, width.""" | |
2707 | Widget.__init__(self, master, 'scrollbar', cnf, kw) | |
2708 | def activate(self, index): | |
2709 | """Display the element at INDEX with activebackground and activerelief. | |
2710 | INDEX can be "arrow1","slider" or "arrow2".""" | |
2711 | self.tk.call(self._w, 'activate', index) | |
2712 | def delta(self, deltax, deltay): | |
2713 | """Return the fractional change of the scrollbar setting if it | |
2714 | would be moved by DELTAX or DELTAY pixels.""" | |
2715 | return getdouble( | |
2716 | self.tk.call(self._w, 'delta', deltax, deltay)) | |
2717 | def fraction(self, x, y): | |
2718 | """Return the fractional value which corresponds to a slider | |
2719 | position of X,Y.""" | |
2720 | return getdouble(self.tk.call(self._w, 'fraction', x, y)) | |
2721 | def identify(self, x, y): | |
2722 | """Return the element under position X,Y as one of | |
2723 | "arrow1","slider","arrow2" or "".""" | |
2724 | return self.tk.call(self._w, 'identify', x, y) | |
2725 | def get(self): | |
2726 | """Return the current fractional values (upper and lower end) | |
2727 | of the slider position.""" | |
2728 | return self._getdoubles(self.tk.call(self._w, 'get')) | |
2729 | def set(self, *args): | |
2730 | """Set the fractional values of the slider position (upper and | |
2731 | lower ends as value between 0 and 1).""" | |
2732 | self.tk.call((self._w, 'set') + args) | |
2733 | ||
2734 | ||
2735 | ||
2736 | class Text(Widget): | |
2737 | """Text widget which can display text in various forms.""" | |
2738 | def __init__(self, master=None, cnf={}, **kw): | |
2739 | """Construct a text widget with the parent MASTER. | |
2740 | ||
2741 | STANDARD OPTIONS | |
2742 | ||
2743 | background, borderwidth, cursor, | |
2744 | exportselection, font, foreground, | |
2745 | highlightbackground, highlightcolor, | |
2746 | highlightthickness, insertbackground, | |
2747 | insertborderwidth, insertofftime, | |
2748 | insertontime, insertwidth, padx, pady, | |
2749 | relief, selectbackground, | |
2750 | selectborderwidth, selectforeground, | |
2751 | setgrid, takefocus, | |
2752 | xscrollcommand, yscrollcommand, | |
2753 | ||
2754 | WIDGET-SPECIFIC OPTIONS | |
2755 | ||
2756 | autoseparators, height, maxundo, | |
2757 | spacing1, spacing2, spacing3, | |
2758 | state, tabs, undo, width, wrap, | |
2759 | ||
2760 | """ | |
2761 | Widget.__init__(self, master, 'text', cnf, kw) | |
2762 | def bbox(self, *args): | |
2763 | """Return a tuple of (x,y,width,height) which gives the bounding | |
2764 | box of the visible part of the character at the index in ARGS.""" | |
2765 | return self._getints( | |
2766 | self.tk.call((self._w, 'bbox') + args)) or None | |
2767 | def tk_textSelectTo(self, index): | |
2768 | self.tk.call('tk_textSelectTo', self._w, index) | |
2769 | def tk_textBackspace(self): | |
2770 | self.tk.call('tk_textBackspace', self._w) | |
2771 | def tk_textIndexCloser(self, a, b, c): | |
2772 | self.tk.call('tk_textIndexCloser', self._w, a, b, c) | |
2773 | def tk_textResetAnchor(self, index): | |
2774 | self.tk.call('tk_textResetAnchor', self._w, index) | |
2775 | def compare(self, index1, op, index2): | |
2776 | """Return whether between index INDEX1 and index INDEX2 the | |
2777 | relation OP is satisfied. OP is one of <, <=, ==, >=, >, or !=.""" | |
2778 | return self.tk.getboolean(self.tk.call( | |
2779 | self._w, 'compare', index1, op, index2)) | |
2780 | def debug(self, boolean=None): | |
2781 | """Turn on the internal consistency checks of the B-Tree inside the text | |
2782 | widget according to BOOLEAN.""" | |
2783 | return self.tk.getboolean(self.tk.call( | |
2784 | self._w, 'debug', boolean)) | |
2785 | def delete(self, index1, index2=None): | |
2786 | """Delete the characters between INDEX1 and INDEX2 (not included).""" | |
2787 | self.tk.call(self._w, 'delete', index1, index2) | |
2788 | def dlineinfo(self, index): | |
2789 | """Return tuple (x,y,width,height,baseline) giving the bounding box | |
2790 | and baseline position of the visible part of the line containing | |
2791 | the character at INDEX.""" | |
2792 | return self._getints(self.tk.call(self._w, 'dlineinfo', index)) | |
2793 | def dump(self, index1, index2=None, command=None, **kw): | |
2794 | """Return the contents of the widget between index1 and index2. | |
2795 | ||
2796 | The type of contents returned in filtered based on the keyword | |
2797 | parameters; if 'all', 'image', 'mark', 'tag', 'text', or 'window' are | |
2798 | given and true, then the corresponding items are returned. The result | |
2799 | is a list of triples of the form (key, value, index). If none of the | |
2800 | keywords are true then 'all' is used by default. | |
2801 | ||
2802 | If the 'command' argument is given, it is called once for each element | |
2803 | of the list of triples, with the values of each triple serving as the | |
2804 | arguments to the function. In this case the list is not returned.""" | |
2805 | args = [] | |
2806 | func_name = None | |
2807 | result = None | |
2808 | if not command: | |
2809 | # Never call the dump command without the -command flag, since the | |
2810 | # output could involve Tcl quoting and would be a pain to parse | |
2811 | # right. Instead just set the command to build a list of triples | |
2812 | # as if we had done the parsing. | |
2813 | result = [] | |
2814 | def append_triple(key, value, index, result=result): | |
2815 | result.append((key, value, index)) | |
2816 | command = append_triple | |
2817 | try: | |
2818 | if not isinstance(command, str): | |
2819 | func_name = command = self._register(command) | |
2820 | args += ["-command", command] | |
2821 | for key in kw: | |
2822 | if kw[key]: args.append("-" + key) | |
2823 | args.append(index1) | |
2824 | if index2: | |
2825 | args.append(index2) | |
2826 | self.tk.call(self._w, "dump", *args) | |
2827 | return result | |
2828 | finally: | |
2829 | if func_name: | |
2830 | self.deletecommand(func_name) | |
2831 | ||
2832 | ## new in tk8.4 | |
2833 | def edit(self, *args): | |
2834 | """Internal method | |
2835 | ||
2836 | This method controls the undo mechanism and | |
2837 | the modified flag. The exact behavior of the | |
2838 | command depends on the option argument that | |
2839 | follows the edit argument. The following forms | |
2840 | of the command are currently supported: | |
2841 | ||
2842 | edit_modified, edit_redo, edit_reset, edit_separator | |
2843 | and edit_undo | |
2844 | ||
2845 | """ | |
2846 | return self._getints( | |
2847 | self.tk.call((self._w, 'edit') + args)) or () | |
2848 | ||
2849 | def edit_modified(self, arg=None): | |
2850 | """Get or Set the modified flag | |
2851 | ||
2852 | If arg is not specified, returns the modified | |
2853 | flag of the widget. The insert, delete, edit undo and | |
2854 | edit redo commands or the user can set or clear the | |
2855 | modified flag. If boolean is specified, sets the | |
2856 | modified flag of the widget to arg. | |
2857 | """ | |
2858 | return self.edit("modified", arg) | |
2859 | ||
2860 | def edit_redo(self): | |
2861 | """Redo the last undone edit | |
2862 | ||
2863 | When the undo option is true, reapplies the last | |
2864 | undone edits provided no other edits were done since | |
2865 | then. Generates an error when the redo stack is empty. | |
2866 | Does nothing when the undo option is false. | |
2867 | """ | |
2868 | return self.edit("redo") | |
2869 | ||
2870 | def edit_reset(self): | |
2871 | """Clears the undo and redo stacks | |
2872 | """ | |
2873 | return self.edit("reset") | |
2874 | ||
2875 | def edit_separator(self): | |
2876 | """Inserts a separator (boundary) on the undo stack. | |
2877 | ||
2878 | Does nothing when the undo option is false | |
2879 | """ | |
2880 | return self.edit("separator") | |
2881 | ||
2882 | def edit_undo(self): | |
2883 | """Undoes the last edit action | |
2884 | ||
2885 | If the undo option is true. An edit action is defined | |
2886 | as all the insert and delete commands that are recorded | |
2887 | on the undo stack in between two separators. Generates | |
2888 | an error when the undo stack is empty. Does nothing | |
2889 | when the undo option is false | |
2890 | """ | |
2891 | return self.edit("undo") | |
2892 | ||
2893 | def get(self, index1, index2=None): | |
2894 | """Return the text from INDEX1 to INDEX2 (not included).""" | |
2895 | return self.tk.call(self._w, 'get', index1, index2) | |
2896 | # (Image commands are new in 8.0) | |
2897 | def image_cget(self, index, option): | |
2898 | """Return the value of OPTION of an embedded image at INDEX.""" | |
2899 | if option[:1] != "-": | |
2900 | option = "-" + option | |
2901 | if option[-1:] == "_": | |
2902 | option = option[:-1] | |
2903 | return self.tk.call(self._w, "image", "cget", index, option) | |
2904 | def image_configure(self, index, cnf=None, **kw): | |
2905 | """Configure an embedded image at INDEX.""" | |
2906 | return self._configure(('image', 'configure', index), cnf, kw) | |
2907 | def image_create(self, index, cnf={}, **kw): | |
2908 | """Create an embedded image at INDEX.""" | |
2909 | return self.tk.call( | |
2910 | self._w, "image", "create", index, | |
2911 | *self._options(cnf, kw)) | |
2912 | def image_names(self): | |
2913 | """Return all names of embedded images in this widget.""" | |
2914 | return self.tk.call(self._w, "image", "names") | |
2915 | def index(self, index): | |
2916 | """Return the index in the form line.char for INDEX.""" | |
2917 | return self.tk.call(self._w, 'index', index) | |
2918 | def insert(self, index, chars, *args): | |
2919 | """Insert CHARS before the characters at INDEX. An additional | |
2920 | tag can be given in ARGS. Additional CHARS and tags can follow in ARGS.""" | |
2921 | self.tk.call((self._w, 'insert', index, chars) + args) | |
2922 | def mark_gravity(self, markName, direction=None): | |
2923 | """Change the gravity of a mark MARKNAME to DIRECTION (LEFT or RIGHT). | |
2924 | Return the current value if None is given for DIRECTION.""" | |
2925 | return self.tk.call( | |
2926 | (self._w, 'mark', 'gravity', markName, direction)) | |
2927 | def mark_names(self): | |
2928 | """Return all mark names.""" | |
2929 | return self.tk.splitlist(self.tk.call( | |
2930 | self._w, 'mark', 'names')) | |
2931 | def mark_set(self, markName, index): | |
2932 | """Set mark MARKNAME before the character at INDEX.""" | |
2933 | self.tk.call(self._w, 'mark', 'set', markName, index) | |
2934 | def mark_unset(self, *markNames): | |
2935 | """Delete all marks in MARKNAMES.""" | |
2936 | self.tk.call((self._w, 'mark', 'unset') + markNames) | |
2937 | def mark_next(self, index): | |
2938 | """Return the name of the next mark after INDEX.""" | |
2939 | return self.tk.call(self._w, 'mark', 'next', index) or None | |
2940 | def mark_previous(self, index): | |
2941 | """Return the name of the previous mark before INDEX.""" | |
2942 | return self.tk.call(self._w, 'mark', 'previous', index) or None | |
2943 | def scan_mark(self, x, y): | |
2944 | """Remember the current X, Y coordinates.""" | |
2945 | self.tk.call(self._w, 'scan', 'mark', x, y) | |
2946 | def scan_dragto(self, x, y): | |
2947 | """Adjust the view of the text to 10 times the | |
2948 | difference between X and Y and the coordinates given in | |
2949 | scan_mark.""" | |
2950 | self.tk.call(self._w, 'scan', 'dragto', x, y) | |
2951 | def search(self, pattern, index, stopindex=None, | |
2952 | forwards=None, backwards=None, exact=None, | |
2953 | regexp=None, nocase=None, count=None): | |
2954 | """Search PATTERN beginning from INDEX until STOPINDEX. | |
2955 | Return the index of the first character of a match or an empty string.""" | |
2956 | args = [self._w, 'search'] | |
2957 | if forwards: args.append('-forwards') | |
2958 | if backwards: args.append('-backwards') | |
2959 | if exact: args.append('-exact') | |
2960 | if regexp: args.append('-regexp') | |
2961 | if nocase: args.append('-nocase') | |
2962 | if count: args.append('-count'); args.append(count) | |
2963 | if pattern[0] == '-': args.append('--') | |
2964 | args.append(pattern) | |
2965 | args.append(index) | |
2966 | if stopindex: args.append(stopindex) | |
2967 | return self.tk.call(tuple(args)) | |
2968 | def see(self, index): | |
2969 | """Scroll such that the character at INDEX is visible.""" | |
2970 | self.tk.call(self._w, 'see', index) | |
2971 | def tag_add(self, tagName, index1, *args): | |
2972 | """Add tag TAGNAME to all characters between INDEX1 and index2 in ARGS. | |
2973 | Additional pairs of indices may follow in ARGS.""" | |
2974 | self.tk.call( | |
2975 | (self._w, 'tag', 'add', tagName, index1) + args) | |
2976 | def tag_unbind(self, tagName, sequence, funcid=None): | |
2977 | """Unbind for all characters with TAGNAME for event SEQUENCE the | |
2978 | function identified with FUNCID.""" | |
2979 | self.tk.call(self._w, 'tag', 'bind', tagName, sequence, '') | |
2980 | if funcid: | |
2981 | self.deletecommand(funcid) | |
2982 | def tag_bind(self, tagName, sequence, func, add=None): | |
2983 | """Bind to all characters with TAGNAME at event SEQUENCE a call to function FUNC. | |
2984 | ||
2985 | An additional boolean parameter ADD specifies whether FUNC will be | |
2986 | called additionally to the other bound function or whether it will | |
2987 | replace the previous function. See bind for the return value.""" | |
2988 | return self._bind((self._w, 'tag', 'bind', tagName), | |
2989 | sequence, func, add) | |
2990 | def tag_cget(self, tagName, option): | |
2991 | """Return the value of OPTION for tag TAGNAME.""" | |
2992 | if option[:1] != '-': | |
2993 | option = '-' + option | |
2994 | if option[-1:] == '_': | |
2995 | option = option[:-1] | |
2996 | return self.tk.call(self._w, 'tag', 'cget', tagName, option) | |
2997 | def tag_configure(self, tagName, cnf=None, **kw): | |
2998 | """Configure a tag TAGNAME.""" | |
2999 | return self._configure(('tag', 'configure', tagName), cnf, kw) | |
3000 | tag_config = tag_configure | |
3001 | def tag_delete(self, *tagNames): | |
3002 | """Delete all tags in TAGNAMES.""" | |
3003 | self.tk.call((self._w, 'tag', 'delete') + tagNames) | |
3004 | def tag_lower(self, tagName, belowThis=None): | |
3005 | """Change the priority of tag TAGNAME such that it is lower | |
3006 | than the priority of BELOWTHIS.""" | |
3007 | self.tk.call(self._w, 'tag', 'lower', tagName, belowThis) | |
3008 | def tag_names(self, index=None): | |
3009 | """Return a list of all tag names.""" | |
3010 | return self.tk.splitlist( | |
3011 | self.tk.call(self._w, 'tag', 'names', index)) | |
3012 | def tag_nextrange(self, tagName, index1, index2=None): | |
3013 | """Return a list of start and end index for the first sequence of | |
3014 | characters between INDEX1 and INDEX2 which all have tag TAGNAME. | |
3015 | The text is searched forward from INDEX1.""" | |
3016 | return self.tk.splitlist(self.tk.call( | |
3017 | self._w, 'tag', 'nextrange', tagName, index1, index2)) | |
3018 | def tag_prevrange(self, tagName, index1, index2=None): | |
3019 | """Return a list of start and end index for the first sequence of | |
3020 | characters between INDEX1 and INDEX2 which all have tag TAGNAME. | |
3021 | The text is searched backwards from INDEX1.""" | |
3022 | return self.tk.splitlist(self.tk.call( | |
3023 | self._w, 'tag', 'prevrange', tagName, index1, index2)) | |
3024 | def tag_raise(self, tagName, aboveThis=None): | |
3025 | """Change the priority of tag TAGNAME such that it is higher | |
3026 | than the priority of ABOVETHIS.""" | |
3027 | self.tk.call( | |
3028 | self._w, 'tag', 'raise', tagName, aboveThis) | |
3029 | def tag_ranges(self, tagName): | |
3030 | """Return a list of ranges of text which have tag TAGNAME.""" | |
3031 | return self.tk.splitlist(self.tk.call( | |
3032 | self._w, 'tag', 'ranges', tagName)) | |
3033 | def tag_remove(self, tagName, index1, index2=None): | |
3034 | """Remove tag TAGNAME from all characters between INDEX1 and INDEX2.""" | |
3035 | self.tk.call( | |
3036 | self._w, 'tag', 'remove', tagName, index1, index2) | |
3037 | def window_cget(self, index, option): | |
3038 | """Return the value of OPTION of an embedded window at INDEX.""" | |
3039 | if option[:1] != '-': | |
3040 | option = '-' + option | |
3041 | if option[-1:] == '_': | |
3042 | option = option[:-1] | |
3043 | return self.tk.call(self._w, 'window', 'cget', index, option) | |
3044 | def window_configure(self, index, cnf=None, **kw): | |
3045 | """Configure an embedded window at INDEX.""" | |
3046 | return self._configure(('window', 'configure', index), cnf, kw) | |
3047 | window_config = window_configure | |
3048 | def window_create(self, index, cnf={}, **kw): | |
3049 | """Create a window at INDEX.""" | |
3050 | self.tk.call( | |
3051 | (self._w, 'window', 'create', index) | |
3052 | + self._options(cnf, kw)) | |
3053 | def window_names(self): | |
3054 | """Return all names of embedded windows in this widget.""" | |
3055 | return self.tk.splitlist( | |
3056 | self.tk.call(self._w, 'window', 'names')) | |
3057 | def xview(self, *what): | |
3058 | """Query and change horizontal position of the view.""" | |
3059 | if not what: | |
3060 | return self._getdoubles(self.tk.call(self._w, 'xview')) | |
3061 | self.tk.call((self._w, 'xview') + what) | |
3062 | def xview_moveto(self, fraction): | |
3063 | """Adjusts the view in the window so that FRACTION of the | |
3064 | total width of the canvas is off-screen to the left.""" | |
3065 | self.tk.call(self._w, 'xview', 'moveto', fraction) | |
3066 | def xview_scroll(self, number, what): | |
3067 | """Shift the x-view according to NUMBER which is measured | |
3068 | in "units" or "pages" (WHAT).""" | |
3069 | self.tk.call(self._w, 'xview', 'scroll', number, what) | |
3070 | def yview(self, *what): | |
3071 | """Query and change vertical position of the view.""" | |
3072 | if not what: | |
3073 | return self._getdoubles(self.tk.call(self._w, 'yview')) | |
3074 | self.tk.call((self._w, 'yview') + what) | |
3075 | def yview_moveto(self, fraction): | |
3076 | """Adjusts the view in the window so that FRACTION of the | |
3077 | total height of the canvas is off-screen to the top.""" | |
3078 | self.tk.call(self._w, 'yview', 'moveto', fraction) | |
3079 | def yview_scroll(self, number, what): | |
3080 | """Shift the y-view according to NUMBER which is measured | |
3081 | in "units" or "pages" (WHAT).""" | |
3082 | self.tk.call(self._w, 'yview', 'scroll', number, what) | |
3083 | def yview_pickplace(self, *what): | |
3084 | """Obsolete function, use see.""" | |
3085 | self.tk.call((self._w, 'yview', '-pickplace') + what) | |
3086 | ||
3087 | ||
3088 | class _setit: | |
3089 | """Internal class. It wraps the command in the widget OptionMenu.""" | |
3090 | def __init__(self, var, value, callback=None): | |
3091 | self.__value = value | |
3092 | self.__var = var | |
3093 | self.__callback = callback | |
3094 | def __call__(self, *args): | |
3095 | self.__var.set(self.__value) | |
3096 | if self.__callback: | |
3097 | self.__callback(self.__value, *args) | |
3098 | ||
3099 | class OptionMenu(Menubutton): | |
3100 | """OptionMenu which allows the user to select a value from a menu.""" | |
3101 | def __init__(self, master, variable, value, *values, **kwargs): | |
3102 | """Construct an optionmenu widget with the parent MASTER, with | |
3103 | the resource textvariable set to VARIABLE, the initially selected | |
3104 | value VALUE, the other menu values VALUES and an additional | |
3105 | keyword argument command.""" | |
3106 | kw = {"borderwidth": 2, "textvariable": variable, | |
3107 | "indicatoron": 1, "relief": RAISED, "anchor": "c", | |
3108 | "highlightthickness": 2} | |
3109 | Widget.__init__(self, master, "menubutton", kw) | |
3110 | self.widgetName = 'tk_optionMenu' | |
3111 | menu = self.__menu = Menu(self, name="menu", tearoff=0) | |
3112 | self.menuname = menu._w | |
3113 | # 'command' is the only supported keyword | |
3114 | callback = kwargs.get('command') | |
3115 | if kwargs.has_key('command'): | |
3116 | del kwargs['command'] | |
3117 | if kwargs: | |
3118 | raise TclError, 'unknown option -'+kwargs.keys()[0] | |
3119 | menu.add_command(label=value, | |
3120 | command=_setit(variable, value, callback)) | |
3121 | for v in values: | |
3122 | menu.add_command(label=v, | |
3123 | command=_setit(variable, v, callback)) | |
3124 | self["menu"] = menu | |
3125 | ||
3126 | def __getitem__(self, name): | |
3127 | if name == 'menu': | |
3128 | return self.__menu | |
3129 | return Widget.__getitem__(self, name) | |
3130 | ||
3131 | def destroy(self): | |
3132 | """Destroy this widget and the associated menu.""" | |
3133 | Menubutton.destroy(self) | |
3134 | self.__menu = None | |
3135 | ||
3136 | class Image: | |
3137 | """Base class for images.""" | |
3138 | _last_id = 0 | |
3139 | def __init__(self, imgtype, name=None, cnf={}, master=None, **kw): | |
3140 | self.name = None | |
3141 | if not master: | |
3142 | master = _default_root | |
3143 | if not master: | |
3144 | raise RuntimeError, 'Too early to create image' | |
3145 | self.tk = master.tk | |
3146 | if not name: | |
3147 | Image._last_id += 1 | |
3148 | name = "pyimage%r" % (Image._last_id,) # tk itself would use image<x> | |
3149 | # The following is needed for systems where id(x) | |
3150 | # can return a negative number, such as Linux/m68k: | |
3151 | if name[0] == '-': name = '_' + name[1:] | |
3152 | if kw and cnf: cnf = _cnfmerge((cnf, kw)) | |
3153 | elif kw: cnf = kw | |
3154 | options = () | |
3155 | for k, v in cnf.items(): | |
3156 | if callable(v): | |
3157 | v = self._register(v) | |
3158 | options = options + ('-'+k, v) | |
3159 | self.tk.call(('image', 'create', imgtype, name,) + options) | |
3160 | self.name = name | |
3161 | def __str__(self): return self.name | |
3162 | def __del__(self): | |
3163 | if self.name: | |
3164 | try: | |
3165 | self.tk.call('image', 'delete', self.name) | |
3166 | except TclError: | |
3167 | # May happen if the root was destroyed | |
3168 | pass | |
3169 | def __setitem__(self, key, value): | |
3170 | self.tk.call(self.name, 'configure', '-'+key, value) | |
3171 | def __getitem__(self, key): | |
3172 | return self.tk.call(self.name, 'configure', '-'+key) | |
3173 | def configure(self, **kw): | |
3174 | """Configure the image.""" | |
3175 | res = () | |
3176 | for k, v in _cnfmerge(kw).items(): | |
3177 | if v is not None: | |
3178 | if k[-1] == '_': k = k[:-1] | |
3179 | if callable(v): | |
3180 | v = self._register(v) | |
3181 | res = res + ('-'+k, v) | |
3182 | self.tk.call((self.name, 'config') + res) | |
3183 | config = configure | |
3184 | def height(self): | |
3185 | """Return the height of the image.""" | |
3186 | return getint( | |
3187 | self.tk.call('image', 'height', self.name)) | |
3188 | def type(self): | |
3189 | """Return the type of the imgage, e.g. "photo" or "bitmap".""" | |
3190 | return self.tk.call('image', 'type', self.name) | |
3191 | def width(self): | |
3192 | """Return the width of the image.""" | |
3193 | return getint( | |
3194 | self.tk.call('image', 'width', self.name)) | |
3195 | ||
3196 | class PhotoImage(Image): | |
3197 | """Widget which can display colored images in GIF, PPM/PGM format.""" | |
3198 | def __init__(self, name=None, cnf={}, master=None, **kw): | |
3199 | """Create an image with NAME. | |
3200 | ||
3201 | Valid resource names: data, format, file, gamma, height, palette, | |
3202 | width.""" | |
3203 | Image.__init__(self, 'photo', name, cnf, master, **kw) | |
3204 | def blank(self): | |
3205 | """Display a transparent image.""" | |
3206 | self.tk.call(self.name, 'blank') | |
3207 | def cget(self, option): | |
3208 | """Return the value of OPTION.""" | |
3209 | return self.tk.call(self.name, 'cget', '-' + option) | |
3210 | # XXX config | |
3211 | def __getitem__(self, key): | |
3212 | return self.tk.call(self.name, 'cget', '-' + key) | |
3213 | # XXX copy -from, -to, ...? | |
3214 | def copy(self): | |
3215 | """Return a new PhotoImage with the same image as this widget.""" | |
3216 | destImage = PhotoImage() | |
3217 | self.tk.call(destImage, 'copy', self.name) | |
3218 | return destImage | |
3219 | def zoom(self,x,y=''): | |
3220 | """Return a new PhotoImage with the same image as this widget | |
3221 | but zoom it with X and Y.""" | |
3222 | destImage = PhotoImage() | |
3223 | if y=='': y=x | |
3224 | self.tk.call(destImage, 'copy', self.name, '-zoom',x,y) | |
3225 | return destImage | |
3226 | def subsample(self,x,y=''): | |
3227 | """Return a new PhotoImage based on the same image as this widget | |
3228 | but use only every Xth or Yth pixel.""" | |
3229 | destImage = PhotoImage() | |
3230 | if y=='': y=x | |
3231 | self.tk.call(destImage, 'copy', self.name, '-subsample',x,y) | |
3232 | return destImage | |
3233 | def get(self, x, y): | |
3234 | """Return the color (red, green, blue) of the pixel at X,Y.""" | |
3235 | return self.tk.call(self.name, 'get', x, y) | |
3236 | def put(self, data, to=None): | |
3237 | """Put row formated colors to image starting from | |
3238 | position TO, e.g. image.put("{red green} {blue yellow}", to=(4,6))""" | |
3239 | args = (self.name, 'put', data) | |
3240 | if to: | |
3241 | if to[0] == '-to': | |
3242 | to = to[1:] | |
3243 | args = args + ('-to',) + tuple(to) | |
3244 | self.tk.call(args) | |
3245 | # XXX read | |
3246 | def write(self, filename, format=None, from_coords=None): | |
3247 | """Write image to file FILENAME in FORMAT starting from | |
3248 | position FROM_COORDS.""" | |
3249 | args = (self.name, 'write', filename) | |
3250 | if format: | |
3251 | args = args + ('-format', format) | |
3252 | if from_coords: | |
3253 | args = args + ('-from',) + tuple(from_coords) | |
3254 | self.tk.call(args) | |
3255 | ||
3256 | class BitmapImage(Image): | |
3257 | """Widget which can display a bitmap.""" | |
3258 | def __init__(self, name=None, cnf={}, master=None, **kw): | |
3259 | """Create a bitmap with NAME. | |
3260 | ||
3261 | Valid resource names: background, data, file, foreground, maskdata, maskfile.""" | |
3262 | Image.__init__(self, 'bitmap', name, cnf, master, **kw) | |
3263 | ||
3264 | def image_names(): return _default_root.tk.call('image', 'names') | |
3265 | def image_types(): return _default_root.tk.call('image', 'types') | |
3266 | ||
3267 | ||
3268 | class Spinbox(Widget): | |
3269 | """spinbox widget.""" | |
3270 | def __init__(self, master=None, cnf={}, **kw): | |
3271 | """Construct a spinbox widget with the parent MASTER. | |
3272 | ||
3273 | STANDARD OPTIONS | |
3274 | ||
3275 | activebackground, background, borderwidth, | |
3276 | cursor, exportselection, font, foreground, | |
3277 | highlightbackground, highlightcolor, | |
3278 | highlightthickness, insertbackground, | |
3279 | insertborderwidth, insertofftime, | |
3280 | insertontime, insertwidth, justify, relief, | |
3281 | repeatdelay, repeatinterval, | |
3282 | selectbackground, selectborderwidth | |
3283 | selectforeground, takefocus, textvariable | |
3284 | xscrollcommand. | |
3285 | ||
3286 | WIDGET-SPECIFIC OPTIONS | |
3287 | ||
3288 | buttonbackground, buttoncursor, | |
3289 | buttondownrelief, buttonuprelief, | |
3290 | command, disabledbackground, | |
3291 | disabledforeground, format, from, | |
3292 | invalidcommand, increment, | |
3293 | readonlybackground, state, to, | |
3294 | validate, validatecommand values, | |
3295 | width, wrap, | |
3296 | """ | |
3297 | Widget.__init__(self, master, 'spinbox', cnf, kw) | |
3298 | ||
3299 | def bbox(self, index): | |
3300 | """Return a tuple of X1,Y1,X2,Y2 coordinates for a | |
3301 | rectangle which encloses the character given by index. | |
3302 | ||
3303 | The first two elements of the list give the x and y | |
3304 | coordinates of the upper-left corner of the screen | |
3305 | area covered by the character (in pixels relative | |
3306 | to the widget) and the last two elements give the | |
3307 | width and height of the character, in pixels. The | |
3308 | bounding box may refer to a region outside the | |
3309 | visible area of the window. | |
3310 | """ | |
3311 | return self.tk.call(self._w, 'bbox', index) | |
3312 | ||
3313 | def delete(self, first, last=None): | |
3314 | """Delete one or more elements of the spinbox. | |
3315 | ||
3316 | First is the index of the first character to delete, | |
3317 | and last is the index of the character just after | |
3318 | the last one to delete. If last isn't specified it | |
3319 | defaults to first+1, i.e. a single character is | |
3320 | deleted. This command returns an empty string. | |
3321 | """ | |
3322 | return self.tk.call(self._w, 'delete', first, last) | |
3323 | ||
3324 | def get(self): | |
3325 | """Returns the spinbox's string""" | |
3326 | return self.tk.call(self._w, 'get') | |
3327 | ||
3328 | def icursor(self, index): | |
3329 | """Alter the position of the insertion cursor. | |
3330 | ||
3331 | The insertion cursor will be displayed just before | |
3332 | the character given by index. Returns an empty string | |
3333 | """ | |
3334 | return self.tk.call(self._w, 'icursor', index) | |
3335 | ||
3336 | def identify(self, x, y): | |
3337 | """Returns the name of the widget at position x, y | |
3338 | ||
3339 | Return value is one of: none, buttondown, buttonup, entry | |
3340 | """ | |
3341 | return self.tk.call(self._w, 'identify', x, y) | |
3342 | ||
3343 | def index(self, index): | |
3344 | """Returns the numerical index corresponding to index | |
3345 | """ | |
3346 | return self.tk.call(self._w, 'index', index) | |
3347 | ||
3348 | def insert(self, index, s): | |
3349 | """Insert string s at index | |
3350 | ||
3351 | Returns an empty string. | |
3352 | """ | |
3353 | return self.tk.call(self._w, 'insert', index, s) | |
3354 | ||
3355 | def invoke(self, element): | |
3356 | """Causes the specified element to be invoked | |
3357 | ||
3358 | The element could be buttondown or buttonup | |
3359 | triggering the action associated with it. | |
3360 | """ | |
3361 | return self.tk.call(self._w, 'invoke', element) | |
3362 | ||
3363 | def scan(self, *args): | |
3364 | """Internal function.""" | |
3365 | return self._getints( | |
3366 | self.tk.call((self._w, 'scan') + args)) or () | |
3367 | ||
3368 | def scan_mark(self, x): | |
3369 | """Records x and the current view in the spinbox window; | |
3370 | ||
3371 | used in conjunction with later scan dragto commands. | |
3372 | Typically this command is associated with a mouse button | |
3373 | press in the widget. It returns an empty string. | |
3374 | """ | |
3375 | return self.scan("mark", x) | |
3376 | ||
3377 | def scan_dragto(self, x): | |
3378 | """Compute the difference between the given x argument | |
3379 | and the x argument to the last scan mark command | |
3380 | ||
3381 | It then adjusts the view left or right by 10 times the | |
3382 | difference in x-coordinates. This command is typically | |
3383 | associated with mouse motion events in the widget, to | |
3384 | produce the effect of dragging the spinbox at high speed | |
3385 | through the window. The return value is an empty string. | |
3386 | """ | |
3387 | return self.scan("dragto", x) | |
3388 | ||
3389 | def selection(self, *args): | |
3390 | """Internal function.""" | |
3391 | return self._getints( | |
3392 | self.tk.call((self._w, 'selection') + args)) or () | |
3393 | ||
3394 | def selection_adjust(self, index): | |
3395 | """Locate the end of the selection nearest to the character | |
3396 | given by index, | |
3397 | ||
3398 | Then adjust that end of the selection to be at index | |
3399 | (i.e including but not going beyond index). The other | |
3400 | end of the selection is made the anchor point for future | |
3401 | select to commands. If the selection isn't currently in | |
3402 | the spinbox, then a new selection is created to include | |
3403 | the characters between index and the most recent selection | |
3404 | anchor point, inclusive. Returns an empty string. | |
3405 | """ | |
3406 | return self.selection("adjust", index) | |
3407 | ||
3408 | def selection_clear(self): | |
3409 | """Clear the selection | |
3410 | ||
3411 | If the selection isn't in this widget then the | |
3412 | command has no effect. Returns an empty string. | |
3413 | """ | |
3414 | return self.selection("clear") | |
3415 | ||
3416 | def selection_element(self, element=None): | |
3417 | """Sets or gets the currently selected element. | |
3418 | ||
3419 | If a spinbutton element is specified, it will be | |
3420 | displayed depressed | |
3421 | """ | |
3422 | return self.selection("element", element) | |
3423 | ||
3424 | ########################################################################### | |
3425 | ||
3426 | class LabelFrame(Widget): | |
3427 | """labelframe widget.""" | |
3428 | def __init__(self, master=None, cnf={}, **kw): | |
3429 | """Construct a labelframe widget with the parent MASTER. | |
3430 | ||
3431 | STANDARD OPTIONS | |
3432 | ||
3433 | borderwidth, cursor, font, foreground, | |
3434 | highlightbackground, highlightcolor, | |
3435 | highlightthickness, padx, pady, relief, | |
3436 | takefocus, text | |
3437 | ||
3438 | WIDGET-SPECIFIC OPTIONS | |
3439 | ||
3440 | background, class, colormap, container, | |
3441 | height, labelanchor, labelwidget, | |
3442 | visual, width | |
3443 | """ | |
3444 | Widget.__init__(self, master, 'labelframe', cnf, kw) | |
3445 | ||
3446 | ######################################################################## | |
3447 | ||
3448 | class PanedWindow(Widget): | |
3449 | """panedwindow widget.""" | |
3450 | def __init__(self, master=None, cnf={}, **kw): | |
3451 | """Construct a panedwindow widget with the parent MASTER. | |
3452 | ||
3453 | STANDARD OPTIONS | |
3454 | ||
3455 | background, borderwidth, cursor, height, | |
3456 | orient, relief, width | |
3457 | ||
3458 | WIDGET-SPECIFIC OPTIONS | |
3459 | ||
3460 | handlepad, handlesize, opaqueresize, | |
3461 | sashcursor, sashpad, sashrelief, | |
3462 | sashwidth, showhandle, | |
3463 | """ | |
3464 | Widget.__init__(self, master, 'panedwindow', cnf, kw) | |
3465 | ||
3466 | def add(self, child, **kw): | |
3467 | """Add a child widget to the panedwindow in a new pane. | |
3468 | ||
3469 | The child argument is the name of the child widget | |
3470 | followed by pairs of arguments that specify how to | |
3471 | manage the windows. Options may have any of the values | |
3472 | accepted by the configure subcommand. | |
3473 | """ | |
3474 | self.tk.call((self._w, 'add', child) + self._options(kw)) | |
3475 | ||
3476 | def remove(self, child): | |
3477 | """Remove the pane containing child from the panedwindow | |
3478 | ||
3479 | All geometry management options for child will be forgotten. | |
3480 | """ | |
3481 | self.tk.call(self._w, 'forget', child) | |
3482 | forget=remove | |
3483 | ||
3484 | def identify(self, x, y): | |
3485 | """Identify the panedwindow component at point x, y | |
3486 | ||
3487 | If the point is over a sash or a sash handle, the result | |
3488 | is a two element list containing the index of the sash or | |
3489 | handle, and a word indicating whether it is over a sash | |
3490 | or a handle, such as {0 sash} or {2 handle}. If the point | |
3491 | is over any other part of the panedwindow, the result is | |
3492 | an empty list. | |
3493 | """ | |
3494 | return self.tk.call(self._w, 'identify', x, y) | |
3495 | ||
3496 | def proxy(self, *args): | |
3497 | """Internal function.""" | |
3498 | return self._getints( | |
3499 | self.tk.call((self._w, 'proxy') + args)) or () | |
3500 | ||
3501 | def proxy_coord(self): | |
3502 | """Return the x and y pair of the most recent proxy location | |
3503 | """ | |
3504 | return self.proxy("coord") | |
3505 | ||
3506 | def proxy_forget(self): | |
3507 | """Remove the proxy from the display. | |
3508 | """ | |
3509 | return self.proxy("forget") | |
3510 | ||
3511 | def proxy_place(self, x, y): | |
3512 | """Place the proxy at the given x and y coordinates. | |
3513 | """ | |
3514 | return self.proxy("place", x, y) | |
3515 | ||
3516 | def sash(self, *args): | |
3517 | """Internal function.""" | |
3518 | return self._getints( | |
3519 | self.tk.call((self._w, 'sash') + args)) or () | |
3520 | ||
3521 | def sash_coord(self, index): | |
3522 | """Return the current x and y pair for the sash given by index. | |
3523 | ||
3524 | Index must be an integer between 0 and 1 less than the | |
3525 | number of panes in the panedwindow. The coordinates given are | |
3526 | those of the top left corner of the region containing the sash. | |
3527 | pathName sash dragto index x y This command computes the | |
3528 | difference between the given coordinates and the coordinates | |
3529 | given to the last sash coord command for the given sash. It then | |
3530 | moves that sash the computed difference. The return value is the | |
3531 | empty string. | |
3532 | """ | |
3533 | return self.sash("coord", index) | |
3534 | ||
3535 | def sash_mark(self, index): | |
3536 | """Records x and y for the sash given by index; | |
3537 | ||
3538 | Used in conjunction with later dragto commands to move the sash. | |
3539 | """ | |
3540 | return self.sash("mark", index) | |
3541 | ||
3542 | def sash_place(self, index, x, y): | |
3543 | """Place the sash given by index at the given coordinates | |
3544 | """ | |
3545 | return self.sash("place", index, x, y) | |
3546 | ||
3547 | def panecget(self, child, option): | |
3548 | """Query a management option for window. | |
3549 | ||
3550 | Option may be any value allowed by the paneconfigure subcommand | |
3551 | """ | |
3552 | return self.tk.call( | |
3553 | (self._w, 'panecget') + (child, '-'+option)) | |
3554 | ||
3555 | def paneconfigure(self, tagOrId, cnf=None, **kw): | |
3556 | """Query or modify the management options for window. | |
3557 | ||
3558 | If no option is specified, returns a list describing all | |
3559 | of the available options for pathName. If option is | |
3560 | specified with no value, then the command returns a list | |
3561 | describing the one named option (this list will be identical | |
3562 | to the corresponding sublist of the value returned if no | |
3563 | option is specified). If one or more option-value pairs are | |
3564 | specified, then the command modifies the given widget | |
3565 | option(s) to have the given value(s); in this case the | |
3566 | command returns an empty string. The following options | |
3567 | are supported: | |
3568 | ||
3569 | after window | |
3570 | Insert the window after the window specified. window | |
3571 | should be the name of a window already managed by pathName. | |
3572 | before window | |
3573 | Insert the window before the window specified. window | |
3574 | should be the name of a window already managed by pathName. | |
3575 | height size | |
3576 | Specify a height for the window. The height will be the | |
3577 | outer dimension of the window including its border, if | |
3578 | any. If size is an empty string, or if -height is not | |
3579 | specified, then the height requested internally by the | |
3580 | window will be used initially; the height may later be | |
3581 | adjusted by the movement of sashes in the panedwindow. | |
3582 | Size may be any value accepted by Tk_GetPixels. | |
3583 | minsize n | |
3584 | Specifies that the size of the window cannot be made | |
3585 | less than n. This constraint only affects the size of | |
3586 | the widget in the paned dimension -- the x dimension | |
3587 | for horizontal panedwindows, the y dimension for | |
3588 | vertical panedwindows. May be any value accepted by | |
3589 | Tk_GetPixels. | |
3590 | padx n | |
3591 | Specifies a non-negative value indicating how much | |
3592 | extra space to leave on each side of the window in | |
3593 | the X-direction. The value may have any of the forms | |
3594 | accepted by Tk_GetPixels. | |
3595 | pady n | |
3596 | Specifies a non-negative value indicating how much | |
3597 | extra space to leave on each side of the window in | |
3598 | the Y-direction. The value may have any of the forms | |
3599 | accepted by Tk_GetPixels. | |
3600 | sticky style | |
3601 | If a window's pane is larger than the requested | |
3602 | dimensions of the window, this option may be used | |
3603 | to position (or stretch) the window within its pane. | |
3604 | Style is a string that contains zero or more of the | |
3605 | characters n, s, e or w. The string can optionally | |
3606 | contains spaces or commas, but they are ignored. Each | |
3607 | letter refers to a side (north, south, east, or west) | |
3608 | that the window will "stick" to. If both n and s | |
3609 | (or e and w) are specified, the window will be | |
3610 | stretched to fill the entire height (or width) of | |
3611 | its cavity. | |
3612 | width size | |
3613 | Specify a width for the window. The width will be | |
3614 | the outer dimension of the window including its | |
3615 | border, if any. If size is an empty string, or | |
3616 | if -width is not specified, then the width requested | |
3617 | internally by the window will be used initially; the | |
3618 | width may later be adjusted by the movement of sashes | |
3619 | in the panedwindow. Size may be any value accepted by | |
3620 | Tk_GetPixels. | |
3621 | ||
3622 | """ | |
3623 | if cnf is None and not kw: | |
3624 | cnf = {} | |
3625 | for x in self.tk.split( | |
3626 | self.tk.call(self._w, | |
3627 | 'paneconfigure', tagOrId)): | |
3628 | cnf[x[0][1:]] = (x[0][1:],) + x[1:] | |
3629 | return cnf | |
3630 | if type(cnf) == StringType and not kw: | |
3631 | x = self.tk.split(self.tk.call( | |
3632 | self._w, 'paneconfigure', tagOrId, '-'+cnf)) | |
3633 | return (x[0][1:],) + x[1:] | |
3634 | self.tk.call((self._w, 'paneconfigure', tagOrId) + | |
3635 | self._options(cnf, kw)) | |
3636 | paneconfig = paneconfigure | |
3637 | ||
3638 | def panes(self): | |
3639 | """Returns an ordered list of the child panes.""" | |
3640 | return self.tk.call(self._w, 'panes') | |
3641 | ||
3642 | ###################################################################### | |
3643 | # Extensions: | |
3644 | ||
3645 | class Studbutton(Button): | |
3646 | def __init__(self, master=None, cnf={}, **kw): | |
3647 | Widget.__init__(self, master, 'studbutton', cnf, kw) | |
3648 | self.bind('<Any-Enter>', self.tkButtonEnter) | |
3649 | self.bind('<Any-Leave>', self.tkButtonLeave) | |
3650 | self.bind('<1>', self.tkButtonDown) | |
3651 | self.bind('<ButtonRelease-1>', self.tkButtonUp) | |
3652 | ||
3653 | class Tributton(Button): | |
3654 | def __init__(self, master=None, cnf={}, **kw): | |
3655 | Widget.__init__(self, master, 'tributton', cnf, kw) | |
3656 | self.bind('<Any-Enter>', self.tkButtonEnter) | |
3657 | self.bind('<Any-Leave>', self.tkButtonLeave) | |
3658 | self.bind('<1>', self.tkButtonDown) | |
3659 | self.bind('<ButtonRelease-1>', self.tkButtonUp) | |
3660 | self['fg'] = self['bg'] | |
3661 | self['activebackground'] = self['bg'] | |
3662 | ||
3663 | ###################################################################### | |
3664 | # Test: | |
3665 | ||
3666 | def _test(): | |
3667 | root = Tk() | |
3668 | text = "This is Tcl/Tk version %s" % TclVersion | |
3669 | if TclVersion >= 8.1: | |
3670 | try: | |
3671 | text = text + unicode("\nThis should be a cedilla: \347", | |
3672 | "iso-8859-1") | |
3673 | except NameError: | |
3674 | pass # no unicode support | |
3675 | label = Label(root, text=text) | |
3676 | label.pack() | |
3677 | test = Button(root, text="Click me!", | |
3678 | command=lambda root=root: root.test.configure( | |
3679 | text="[%s]" % root.test['text'])) | |
3680 | test.pack() | |
3681 | root.test = test | |
3682 | quit = Button(root, text="QUIT", command=root.destroy) | |
3683 | quit.pack() | |
3684 | # The following three commands are needed so the window pops | |
3685 | # up on top on Windows... | |
3686 | root.iconify() | |
3687 | root.update() | |
3688 | root.deiconify() | |
3689 | root.mainloop() | |
3690 | ||
3691 | if __name__ == '__main__': | |
3692 | _test() |