1 """
2 Tkinter grab example. -Case Roole
3
4 When destroyed, a window returns the grab with the original status to
5 the window that previously had it. On entering the window that currently
6 has the grab will light up red. You can dismiss only the window that has
7 grabbed focus.
8
9 There is some extra code for taking care of root being destroyed upon the
10 destruction of the last toplevel window.
11
12 PROGRAMMING TIP:
13 grab_set_global can be mighty effective. You'd better provide an escape
14 path before unleashing it, as the window manager will be disabled ;-).
15 Here is a rude on for in the if __name__ == '__main__' definition:
16 root.after(60*1000*2, root.destroy), that is, after two minutes
17 get rid of the windows anyway. Of course, a dismiss button is more elegant.
18
19 """
20
21 from Tkinter import *
22
23 COUNT = 0
24
25 class GrabBack( Toplevel ):
26 def _makeButton(self):
27 self.button = Button(self,text='dismiss',command=self.destroy)
28 self.button.place(relx=0.5,rely=0.5,anchor='c')
29
30 def __init__(self,master):
31 global COUNT
32 COUNT = COUNT + 1
33 Toplevel.__init__(self,master)
34 self.title("window %d" % COUNT)
35 self.bind('<Enter>', lambda e,f=self.configure: f(background='red'))
36 self.bind('<Leave>', lambda e,f=self.configure: f(background='gray80'))
37 self.protocol('WM_DELETE_WINDOW', self.destroy)
38 self._makeButton()
39
40 def nice_grab_set(self):
41 "Store current grab status before grabbing the focus."
42 self.oldgrab = self.grab_current()
43 if self.oldgrab:
44 self.oldgrabstatus = self.oldgrab.grab_status()
45 else:
46 self.oldgrabstatus = None
47 print "oldgrab = %s (%s)" % (self.oldgrab, self.oldgrabstatus)
48 self.grab_set()
49
50 def nice_grab_set_global(self):
51 "Store current grab status before grabbing the focus."
52 self.oldgrab = self.grab_current()
53 if self.oldgrab:
54 self.oldgrabstatus = self.oldgrab.grab_status()
55 else:
56 self.oldgrabstatus = None
57 print "oldgrab = %s (%s)" % (self.oldgrab, self.oldgrabstatus)
58 self.grab_set_global()
59
60 def destroy(self):
61 global COUNT
62 if self.grab_current() and self.grab_current() != self:
63 print "Won't destroy window while other has grab"
64 return
65 if self.oldgrab is not None:
66 if self.oldgrabstatus == 'local':
67 self.oldgrab.grab_set()
68 elif self.oldgrabstatus == 'global':
69 self.oldgrab.grab_set_global()
70 else:
71 print "Weird, oldgrab is not None, but it has status."
72 Toplevel.destroy(self)
73 COUNT = COUNT - 1
74 if COUNT == 0:
75 self.master.destroy()
76
77 def _test():
78 root = Tk()
79 root.protocol('WM_DELETE_WINDOW',root.quit)
80 root.withdraw()
81 root.after(60*1000*1,root.quit)
82
83 top = root
84 for i in range(4):
85 t = GrabBack(top)
86 t.update_idletasks()
87 t.nice_grab_set()
88
89 root.mainloop()
90
91 if __name__ == '__main__':
92 _test()
93