Question: How to Prevent Tkinter Menu from Taking Keyboard Focus
galyle
galyle at gmail.com
Tue Oct 4 14:35:25 EDT 2011
On Oct 4, 11:05 am, galyle <gal... at gmail.com> wrote:
> On Oct 4, 9:45 am, woooee <woo... at gmail.com> wrote:
>
>
>
>
>
>
>
>
>
> > Sorry, I did not understand the question correctly, and so have added
> > another focus_set for the entry after the menu's creation. You can
> > still enter after the menu comes up, even though you can't see where
> > you are entering.
>
> > import Tkinter
>
> > class demo:
> > def __init__(self, parent):
> > self._entry = Tkinter.Entry(width = 60)
> > self._suggestions = Tkinter.Menu(parent, tearoff = 0,
> > takefocus = 0)
> > self._entry.pack(padx = 20, pady = 20)
> > self._entry.bind('<Key>', self._suggest_text, add = '+')
> > self._entry.focus_set()
>
> > def _suggest_text(self, event):
> > curr = self._entry.get() + repr(event.char)[1]
> > x = self._entry.winfo_rootx()
> > y = self._entry.winfo_rooty()
> > y += self._entry.winfo_height()
> > try:
> > self._suggestions.delete(0, 'end')
> > self._suggestions.add_command(label = curr + '_1')
> > self._suggestions.add_command(label = curr + '_2')
> > self._suggestions.add_command(label = curr + '_3')
> > self._suggestions.add_command(label = curr + '_4')
> > self._suggestions.post(x, y)
> > finally:
> > self._suggestions.grab_release()
>
> > self._entry.focus_set()
>
> > if __name__ == '__main__':
> > root = Tkinter.Tk()
> > root.title('A Problem')
> > demo(root)
> > root.mainloop()
>
> Perhaps it is because I'm trying this on Windows, but the above code
> does not work for me. After the menu is posted, no further keyboard
> input gets directed to the entry until the menu is unposted.
>
> It looks like my best bet is to use the ComboBox suggested above. The
> ComboBox method is very close to working, but I've got a problem now
> where all focus on the app is directed to the ComboBox entry (I need
> to set it that way to redirect keyboard input from the popup menu),
> making it impossible to close the app without killing it. I've tried
> to return focus to the entry parent by binding the entry to <FocusOut>
> and <Leave>, but this has the effect of making the popup take the
> focus after every keystroke, which is not what I want.
>
> The (almost working) demo below should demonstrate the issue fairly
> well:
>
> import Tkinter
> import Pmw
>
> class demo:
> def __init__(self, parent):
> self._search_bar = Pmw.ComboBox(parent,
> label_text = 'Register Mnemonic',
> labelpos = 'w', entry_width = 60)
> self._search_bar.pack(padx = 20, pady = 20)
> self._search_bar._entryfield.component('entry').bind('<Key>',
> self._suggest_text, add = '+')
>
> def _suggest_text(self, event):
> curr = self._search_bar._entryfield.getvalue()
> curr += repr(event.char)[1]
> self._search_bar._list.setlist([curr + '_0', curr + '_1',
> curr + '_2'])
> self._search_bar._postList(event)
> self._search_bar._entryfield.component('entry').focus_set()
> self._search_bar._popup.lift()
>
> if __name__ == '__main__':
> root = Tkinter.Tk()
> root.title('A Problem')
> demo(root)
> root.mainloop()
Well, it required quite a bit of digging, but I finally have what I
want. For those who are curious, the following demo should provide
some help:
import Tkinter
import Pmw
class demo:
def __init__(self, parent):
self._parent = parent
self._search_bar = Pmw.ComboBox(parent,
label_text = 'Register Mnemonic',
labelpos = 'w', entry_width = 60)
self._search_bar.pack(padx = 20, pady = 20)
self._search_bar._entryfield.component('entry').bind('<Key>',
self._suggest_text, add = '+')
self._search_bar._entryfield.component('entry').bind('<Escape>',
self._remove_list, add = '+')
self._search_bar._entryfield.component('entry').bind('<space>',
self._remove_list, add = '+')
self._search_bar._entryfield.component('entry').bind('<Return>',
self._remove_list, add = '+')
self._search_bar._popup.bind('<ButtonRelease-1>',
self._remove_list, add = '+')
def _suggest_text(self, event):
x = self._search_bar._entryfield.winfo_rootx()
y = self._search_bar._entryfield.winfo_rooty() + \
self._search_bar._entryfield.winfo_height()
w = self._search_bar._entryfield.winfo_width() + \
self._search_bar._arrowBtn.winfo_width()
curr = self._search_bar._entryfield.getvalue()
curr += repr(event.char)[1]
self._search_bar._list.setlist([curr + '_0', curr + '_1',
curr + '_2'])
self._search_bar._list.configure(hull_width=w)
Pmw.setgeometryanddeiconify(self._search_bar._popup,
'+%d+%d' % (x, y))
self._search_bar._popup.lift()
def _remove_list(self, event):
self._search_bar._popup.withdraw()
if __name__ == '__main__':
root = Tkinter.Tk()
root.title('A Problem')
demo(root)
root.mainloop()
More information about the Python-list
mailing list