Question: How to Prevent Tkinter Menu from Taking Keyboard Focus

2011-10-03 Thread galyle
Hello, I'm trying to build a menu which provides suggestions to a user
based on input to an entry.  I have done something like this before
using Tcl/Tk, so I expected that it would work without much difficulty
with Tkinter.  I was wrong.

The problem I have is that, as soon as the menu is posted, it appears
to take the keyboard focus until the user either selects an option or
clicks an area outside of the menu.  The behavior I would like is for
keyboard input to go to the entry, and for the menu to update based on
that input.  I have tried different bindings (both to the entry and
menu) and I have tried different focus/grab combinations (even
force_focus and grab_set_global to the entry) when the menu is posted,
but nothing seems to work.  Are there any suggestions on how to get
the behavior I'm seeking?  The following code demonstrates the issue
I'm having:


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('', self._suggest_text, add = '+')

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

if __name__ == '__main__':
root = Tkinter.Tk()
root.title('A Problem')
demo(root)
root.mainloop()
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Question: How to Prevent Tkinter Menu from Taking Keyboard Focus

2011-10-03 Thread galyle
On Oct 3, 2:40 pm, rantingrick  wrote:
> On Oct 3, 2:55 pm, galyle  wrote:
>
> > Hello, I'm trying to build a menu which provides suggestions to a user
> > based on input to an entry.  I have done something like this before
> > using Tcl/Tk, so I expected that it would work without much difficulty
> > with Tkinter.  I was wrong.
>
> Why not just use the Tix.ComboBox instead? I believe it's editable.

Thanks for the suggestion.  I tried using a Pmw.ComboBox, but I've run
into essentially the same problem.  If I bring up the selection list
on a keypress, then the selection takes the focus and further input no
longer goes to the entry of the ComboBox.  However, if I set the focus
to the entry after bringing up the selection list, I can at least
continue inputting to the entry, even though the selection list menu
gets placed behind the entry.  This is not desirable behavior, but at
least it is closer.  Any idea how to bring the menu to the forefront
without the entry losing focus?  The following demo demonstrates the
issue:


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('',
self._suggest_text, add = '+')

def _suggest_text(self, event):
curr = self._search_bar._entryfield.getvalue() +
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()
print curr

if __name__ == '__main__':
root = Tkinter.Tk()
root.title('A Problem')
demo(root)
root.mainloop()
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Question: How to Prevent Tkinter Menu from Taking Keyboard Focus

2011-10-04 Thread galyle
On Oct 4, 9:45 am, woooee  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('', 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 
and , 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('',
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()
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Question: How to Prevent Tkinter Menu from Taking Keyboard Focus

2011-10-04 Thread galyle
On Oct 4, 11:05 am, galyle  wrote:
> On Oct 4, 9:45 am, woooee  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('', 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 
> and , 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('',
>             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('',
self._suggest_text, add = '+')
 
self._search_bar._entryfield.component('entry').bind('',
self._remove_list, add = '+')
 
self._search_bar._entryfield.component('entry').bind('',
self._remove_list, add = '+')
 
self._search_bar._entryfield.component('entry').bind('',
self._remove_list, add = '+')
self._search_bar._popup.bind('',
self._remove_list, add = '+')

def _sugges

Question: Optional Regular Expression Grouping

2011-10-10 Thread galyle
HI, I've looked through this forum, but I haven't been able to find a
resolution to the problem I'm having (maybe I didn't look hard enough
-- I have to believe this has come up before).  The problem is this:
I have a file which has 0, 2, or 3 groups that I'd like to record;
however, in the case of 3 groups, the third group is correctly
captured, but the first two groups get collapsed into just one group.
I'm sure that I'm missing something in the way I've constructed my
regular expression, but I can't figure out what's wrong.  Does anyone
have any suggestions?

The demo below showcases the problem I'm having:

import re

valid_line = re.compile('^\[(\S+)\]\[(\S+)\](?:\s+|\[(\S+)\])=|\s+[\d\
[\']+.*$')
line1 = "[field1][field2] = blarg"
line2 = "'a continuation of blarg'"
line3 = "[field1][field2][field3] = blorg"

m = valid_line.match(line1)
print 'Expected: ' + m.group(1) + ', ' + m.group(2)
m = valid_line.match(line2)
print 'Expected: ' + str(m.group(1))
m = valid_line.match(line3)
print 'Uh-oh: ' + m.group(1) + ', ' + m.group(2)
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Question: Optional Regular Expression Grouping

2011-10-10 Thread galyle
On Oct 10, 4:59 pm, Vlastimil Brom  wrote:
> 2011/10/10 galyle :
>
>
>
>
>
>
>
>
>
> > HI, I've looked through this forum, but I haven't been able to find a
> > resolution to the problem I'm having (maybe I didn't look hard enough
> > -- I have to believe this has come up before).  The problem is this:
> > I have a file which has 0, 2, or 3 groups that I'd like to record;
> > however, in the case of 3 groups, the third group is correctly
> > captured, but the first two groups get collapsed into just one group.
> > I'm sure that I'm missing something in the way I've constructed my
> > regular expression, but I can't figure out what's wrong.  Does anyone
> > have any suggestions?
>
> > The demo below showcases the problem I'm having:
>
> > import re
>
> > valid_line = re.compile('^\[(\S+)\]\[(\S+)\](?:\s+|\[(\S+)\])=|\s+[\d\
> > [\']+.*$')
> > line1 = "[field1][field2] = blarg"
> > line2 = "    'a continuation of blarg'"
> > line3 = "[field1][field2][field3] = blorg"
>
> > m = valid_line.match(line1)
> > print 'Expected: ' + m.group(1) + ', ' + m.group(2)
> > m = valid_line.match(line2)
> > print 'Expected: ' + str(m.group(1))
> > m = valid_line.match(line3)
> > print 'Uh-oh: ' + m.group(1) + ', ' + m.group(2)
> > --
> >http://mail.python.org/mailman/listinfo/python-list
>
> Hi,
> I believe, the space before = is causing problems (or the pattern missing it);
> you also need non greedy quantifiers +? to match as little as possible
> as opposed to the greedy default:
>
> valid_line = 
> re.compile('^\[(\S+?)\]\[(\S+?)\](?:\s+|\[(\S+)\])\s*=|\s+[\d\[\']+.*$')
>
> or you can use word-patterns explicitely excluding the closing ], like:
>
> valid_line = 
> re.compile('^\[([^\]]+)\]\[([^\]]+)\](?:\s+|\[([^\]]+)\])\s*=|\s+[\d\[\']+. 
> *$')
>
> hth
>  vbr

Thanks, I had a feeling that greedy matching in my expression was
causing problem.  Your suggestion makes sense to me, and works quite
well.
-- 
http://mail.python.org/mailman/listinfo/python-list