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