1 | from Tkinter import *
|
---|
2 |
|
---|
3 | class WindowList:
|
---|
4 |
|
---|
5 | def __init__(self):
|
---|
6 | self.dict = {}
|
---|
7 | self.callbacks = []
|
---|
8 |
|
---|
9 | def add(self, window):
|
---|
10 | window.after_idle(self.call_callbacks)
|
---|
11 | self.dict[str(window)] = window
|
---|
12 |
|
---|
13 | def delete(self, window):
|
---|
14 | try:
|
---|
15 | del self.dict[str(window)]
|
---|
16 | except KeyError:
|
---|
17 | # Sometimes, destroy() is called twice
|
---|
18 | pass
|
---|
19 | self.call_callbacks()
|
---|
20 |
|
---|
21 | def add_windows_to_menu(self, menu):
|
---|
22 | list = []
|
---|
23 | for key in self.dict.keys():
|
---|
24 | window = self.dict[key]
|
---|
25 | try:
|
---|
26 | title = window.get_title()
|
---|
27 | except TclError:
|
---|
28 | continue
|
---|
29 | list.append((title, window))
|
---|
30 | list.sort()
|
---|
31 | for title, window in list:
|
---|
32 | menu.add_command(label=title, command=window.wakeup)
|
---|
33 |
|
---|
34 | def register_callback(self, callback):
|
---|
35 | self.callbacks.append(callback)
|
---|
36 |
|
---|
37 | def unregister_callback(self, callback):
|
---|
38 | try:
|
---|
39 | self.callbacks.remove(callback)
|
---|
40 | except ValueError:
|
---|
41 | pass
|
---|
42 |
|
---|
43 | def call_callbacks(self):
|
---|
44 | for callback in self.callbacks:
|
---|
45 | try:
|
---|
46 | callback()
|
---|
47 | except:
|
---|
48 | print "warning: callback failed in WindowList", \
|
---|
49 | sys.exc_type, ":", sys.exc_value
|
---|
50 |
|
---|
51 | registry = WindowList()
|
---|
52 |
|
---|
53 | add_windows_to_menu = registry.add_windows_to_menu
|
---|
54 | register_callback = registry.register_callback
|
---|
55 | unregister_callback = registry.unregister_callback
|
---|
56 |
|
---|
57 |
|
---|
58 | class ListedToplevel(Toplevel):
|
---|
59 |
|
---|
60 | def __init__(self, master, **kw):
|
---|
61 | Toplevel.__init__(self, master, kw)
|
---|
62 | registry.add(self)
|
---|
63 | self.focused_widget = self
|
---|
64 |
|
---|
65 | def destroy(self):
|
---|
66 | registry.delete(self)
|
---|
67 | Toplevel.destroy(self)
|
---|
68 | # If this is Idle's last window then quit the mainloop
|
---|
69 | # (Needed for clean exit on Windows 98)
|
---|
70 | if not registry.dict:
|
---|
71 | self.quit()
|
---|
72 |
|
---|
73 | def update_windowlist_registry(self, window):
|
---|
74 | registry.call_callbacks()
|
---|
75 |
|
---|
76 | def get_title(self):
|
---|
77 | # Subclass can override
|
---|
78 | return self.wm_title()
|
---|
79 |
|
---|
80 | def wakeup(self):
|
---|
81 | try:
|
---|
82 | if self.wm_state() == "iconic":
|
---|
83 | self.wm_withdraw()
|
---|
84 | self.wm_deiconify()
|
---|
85 | self.tkraise()
|
---|
86 | self.focused_widget.focus_set()
|
---|
87 | except TclError:
|
---|
88 | # This can happen when the window menu was torn off.
|
---|
89 | # Simply ignore it.
|
---|
90 | pass
|
---|