Other ways to disable Wm in Tkinter?

Tim Evans tre17 at student.canterbury.ac.nz
Mon Nov 15 02:28:41 CET 1999


brian at liaone.ne.mediaone.net writes:

> 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
> 

I've included some code that does a better job of it.  The new window
does actually use a global grab, just the same as a menu window.  The
behaviour matches how the same kind of window behaves in other more
complex widget sets.

==============================
#!/usr/bin/env python

from Tkinter import *
import string

class ScrolledMenu(Toplevel):
    def __init__(self, command=None):
        self.command = command
        Toplevel.__init__(self)
        self.withdraw()
        self.overrideredirect(1)
        self.listbox = Listbox(self)
        scroll = Scrollbar(self, orient='v', command=self.listbox.yview)
        self.listbox.configure(yscrollcommand=scroll.set)
        self.listbox.pack(fill='both', expand=1, side='left')
        scroll.pack(fill='y', side='right')
        self.bind('<ButtonPress-1>', self._press)
        self.bind('<ButtonPress>', self._close)
        self.bind('<KeyPress-Escape>', self._close)
        self.listbox.bind('<ButtonRelease-1>', self._select)
        self.up = 0

    def popup(self, onto):
        x = onto.winfo_rootx()
        y = onto.winfo_rooty() + onto.winfo_height()
        self.geometry('+%d+%d' % (x,y))
        self.deiconify()
        self.up = 1
        self.grab_set_global()

    def _close(self, event=None):
        self.grab_release()
        self.withdraw()
        self.up = 0

    def _select(self, event):
        self.update() # let the listbox change its selection
        self._close()
        index = self.listbox.curselection()
        value = self.listbox.get(index)[0]
        if self.command is not None:
            self.command(value)

    def _press(self, event):
        x,y = self.winfo_pointerxy()
        window = self.winfo_containing(x,y)
        if window is None or window.winfo_toplevel() != self:
            self._close()
            

class _Test(Tk):
    def __init__(self):
        Tk.__init__(self)
        self.sm = ScrolledMenu(self.result)
        apply(self.sm.listbox.insert, (0,)+tuple(string.lowercase))
        self.b= Button(self, text='Test', command=self.popup)
        self.b.pack()

    def result(self, value):
        print 'selected:', value

    def popup(self):
        self.sm.popup(self.b)

if __name__ == '__main__':
    mw = _Test()
    mw.mainloop()
==============================

--
Tim Evans




More information about the Python-list mailing list