Other ways to disable Wm in Tkinter?

brian at liaone.ne.mediaone.net brian at liaone.ne.mediaone.net
Sun Nov 14 22:42:19 CET 1999


Hello,
I have a question on how to dynamically activate/deactivate the window
manager. I'm using a button activated listbox to enter items into an
application. The listbox is on a separate managerless Toplevel to give
it a placard appearance.  When the listbox pops up, it has a local grab.
Unfortanately, one can still drag around the main window underneath
and thus inadvertantly hide the listbox.  I have managed to get around
this problem by using withdraw/overrideredirect/deiconify on the
main window when the listbox appears and again when the listbox
disappears (to restart the window manager).  This is not a good fix
since it results in irritating flashes as the main window is
clobbered and redrawn.

Thus, my question - can one disable the window manager (or at least
disable window movement) short of withdraw/overrideredirect/deiconify?
It goes without saying that using grab_set_global is a bit too brutal.
Thanks,
Brian

------------------here is some example code-------------------------

#!/usr/bin/env python

import sys
from Tkinter import *

controller_list = ['a','b','c','d','e','f','g','h','i','j','k','l','m',
                   'n','o','p','q','r','s','t','u','v','w','x','y','z']

class Right(Frame):
    def __init__(self,master,big):
        self.big = big
        Frame.__init__(self)
        self.right = Frame(master)
        self.right.pack(side=RIGHT)
        for i in range(10):
          for j in range(10):
            self.b = Button(self.right,bg='#44d950',width=8,
                                 height=1,text='button ' + `i` + `j`)
            self.b['command']=lambda cblb=self.callbackCreateListbox,\
                                 r = self.b : cblb(r)
            self.b.grid(row=i,column=j)
    def callbackDestroyListbox(self):
        self.temp.destroy()
    def handleListChoice(self,event):
        label = self.temp.list.get(ACTIVE)
        self.controller_entry['text']=label
        self.temp.destroy() #now we destroy listbox
        self.big.turnOnWm() #now to re-enable the Window Manager
    def callbackCreateListbox(self,controller_entry):
        self.controller_entry = controller_entry
        x0 = controller_entry.winfo_rootx()
        y0 = controller_entry.winfo_rooty() +       \
                           controller_entry.winfo_height()
        self.temp = Toplevel()
        self.temp.geometry("+%d+%d" % (x0, y0))
        self.temp.overrideredirect(1)
        self.temp.scroll = Scrollbar(self.temp)
        self.temp.list = Listbox(self.temp,height=15,width=10,
                                yscrollcommand=self.temp.scroll.set)
        self.temp.list['selectmode']=SINGLE
        self.temp.list.grid(column=0)
        pos = 0
        for controller in controller_list:
            self.temp.list.insert(pos,controller)
            pos = pos+1
        self.temp.scroll.config(command=self.temp.list.yview)
        self.temp.scroll.grid(row=0,column=1,sticky=N+S)
        self.temp.button = Button(self.temp,text='Quit',command=
                                  self.callbackDestroyListbox)
        self.temp.list.bind('<Double-Button-1>',self.handleListChoice)
        self.temp.grab_set() #Almost does the trick-unfortunately Window
                             #manager is unaffected.  Thus, must
                             #withdraw, overrideredirect and deiconify.
                             #Note: using grab_set_global works but is
                             #too brutal.
        self.big.turnOffWm(self.temp.list) #need to give turnOffWm() a
                                           #ref back to this listbox
                                           #for stacking purposes.
class Big(Frame):
    def __init__(self):
        self.placardCnt='even' #even/odd cnt of listboxes
        root = Tk()
        root.withdraw()
        Frame.__init__(self)
        self.top = Toplevel(width=100,height=
                           500,bg='red') #create master Frame
        self.top.protocol("WM_DELETE_WINDOW",root.quit)
        self.right = Right(self.top,self)
    def turnOnWm(self):
        heightOfWm     = -25
        widthOfWmFrame = -5
        x0 = self.top.winfo_x() + widthOfWmFrame
        y0 = self.top.winfo_y() + heightOfWm
        self.top.withdraw()
        self.top.overrideredirect(0)
        self.top.geometry("+%d+%d" % (x0,y0))
        self.top.deiconify()
    def turnOffWm(self,listboxToplevel): # need a handle on listbox to
                                         # place main window(self.top)
                                         # below listbox.
        if self.placardCnt=='even':
            heightOfWm    = 1 #Should =0,but then toplevel
                              #reappears too high up.
            self.placardCnt='odd'  #'increment' placard count
        else:
            heightOfWm    = -1 #A kludge to keep toplevel from slowly
                               #creeping downward.
            self.placardCnt='even' #'increment' placard count
        widthOfWmFrame = 0
        x0 = self.top.winfo_x() + widthOfWmFrame
        y0 = self.top.winfo_y() + heightOfWm
        self.top.withdraw()
        self.top.overrideredirect(1)
        self.top.update_idletasks()
        self.top.geometry("+%d+%d" % (x0,y0))
        self.top.update_idletasks()
        self.top.lower(belowThis=listboxToplevel) #keeps listbox from
                                                  #being obscured.
        self.top.deiconify()

if __name__ == '__main__':
    b = Big()
    b.mainloop()



Sent via Deja.com http://www.deja.com/
Before you buy.




More information about the Python-list mailing list