NiceGrab

   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()     # global grab requires that window is viewable
  87         t.nice_grab_set()
  88         #t.nice_grab_set_global()
  89     root.mainloop()
  90 
  91 if __name__ == '__main__':
  92     _test() 

tkinter: NiceGrab (last edited 2011-06-16 23:44:25 by AnthonyMuss)