Looking into this problem further - it appears the *accepted* way of doing
things is probably with a wxAcceleratorTable?
At any rate - as this wiki page ( http://wiki.wxpython.org/index.cgi/SmallApp ) points out, and I have
confirmed - it appears this "built-in" key binding makes the accelerator
table obsolete as well?
Mark.
Hi all,
I just stumbled across something I imagine everyone *except* me was
already aware of....
I have an application where I was capturing key presses as menu
hotkeys. Well, I coded up all of this logic to hook any EVT_CHAR
and EVT_KEY_UP events to my multitude of child windows and pass them
up to the parent wxFrame. Then, in the parent I have this OnChar
handler which decodes the keycodes and fires methods according to
the Ctrl-Key combination.
Well, it appears this is all useless code! I have recently changed
my menus to be "standard" in that the shortcut key appears after the
menu item label with a tab character and "Ctrl+" the keyname (i.e.
"&Save\tCtrl+S" for save - for example). I use to have them in
brackets with a dash instead of a plus sign. ANYWAY - I have been
trying to figure out why my program behaves differently today - and
wouldn't you know it - wxPython automatically hooks the keys now.
So - I am getting TWO events instead of one.
Here is my problem...I used to be relying on passing NULL as the
event parameter and bypassing certain annoying "Are you sure?"
dialogs if the user pressed the hotkey. Now I can't do that because
the event passed is always valid wxCommandEvent.
First question - Am I right in that wxPython automatically binds the
keyboard shortcuts (if you use the correct syntax)?
Second question - Am I really that much of an idiot and didn't read
the documentation clearly - or is this another one of those 'black
art' tricks known by experienced people?
Third question - Using the automatic key binding feature - what
would be the *correct* way to do what I am trying to do - which is
tell whether or not the user actually clicked the menu or pressed the
hotkey?
Last question - Is it safe to go and rip out all of this crap I have
introduced to implement passing up EVT_CHAR events, and rely on the
auto-bound keys to be active all of the time, no matter what has the
focus?
···
Mark Melvin/Dspfactory wrote on 07/05/2003 10:57:08 AM:
Looking into this problem further - it appears the *accepted* way of doing
things is probably with a wxAcceleratorTable?
Using the text in the menu item is just a shortcut/convenience to using an accelerator table.
At any rate - as this wiki page ( http://wiki.wxpython.org/index.cgi/SmallApp ) points out, and I have
confirmed - it appears this "built-in" key binding makes the accelerator
table obsolete as well?
Not really obsolete, as using an accelerator table will allow you to bind keys that do not have a corresponding menu item, or that are not currently recognized by the menu item parser.
···
--
Robin Dunn
Software Craftsman http://wxPython.org Java give you jitters? Relax with wxPython!
Not really obsolete, as using an accelerator table will allow you to
bind keys that do not have a corresponding menu item, or that are not
currently recognized by the menu item parser.
Is it documented somewhere what the parser will recognize? I assume
Ctrl+<something> and function keys (i.e. 'F1) are supported at a minimum.
On a related note - is there any way to get a reference to the
wxCommandEvent(s) created when issuing:
EVT_MENU(self, someMenuId, someFunction)?
It looks like the automatic generation of the accelerator table entry
simply hooks in a second wxCommandEvent to the menu item. If I had a
reference to the first one - I could test for object equality in the event
handler and know if I am handling the keyboard-generated wxCommandEvent, or
the menu-click-generated one.
Issuing a 'print event, event.GetEventObject(), event.GetEventType()' in my
event handler produces the following output:
# Menu clicked event
<C wxCommandEvent instance at _12f7a4_wxCommandEvent_p> <C wxFrame instance
at _dbd4c8_wxFrame_p> 10007
# Keyboard pressed event
<C wxCommandEvent instance at _12f778_wxCommandEvent_p> <C wxFrame instance
at _dbd4c8_wxFrame_p> 10007
..so they are obviously distinct objects.
Thanks,
Mark.
···
Robin Dunn <robin@alldunn.com> wrote on 07/05/2003 01:35:05 PM: > Mark Melvin wrote:
It does appear the event.this is always the same, however. And it also
appears that it is different between the menu-generated event, and the
keyboard generated one.
···
Robin Dunn <robin@alldunn.com> wrote on 07/05/2003 07:13:08 PM: > > On a related note - is there any way to get a reference to the > > wxCommandEvent(s) created when issuing:
> EVT_MENU(self, someMenuId, someFunction)?
No, a new event object is usually created each time an event is sent.
No, a new event object is usually created each time an event is sent.
Argh! You're right of course.
It does appear the event.this is always the same, however. And it also
appears that it is different between the menu-generated event, and the
keyboard generated one.
I don' think you can depend on that, or at least not on the value staying the same between different runs of the app. You are seeing the same values because the event object is being created at the same place on the stack each time, but it *is* being created each time so if anything happens to be pushed on the stack in different orders, or if the program is loaded in a different place in memory, or a different version of Python or wxPython is used, then the location encoded in event.this will be different.
···
Robin Dunn <robin@alldunn.com> wrote on 07/05/2003 07:13:08 PM: > > >>>On a related note - is there any way to get a reference to the >>>wxCommandEvent(s) created when issuing:
--
Robin Dunn
Software Craftsman http://wxPython.org Java give you jitters? Relax with wxPython!
Thanks, Robin. Yes - I realize that it will only be consistent during a
given instance of the application.
It's kind of hokey to code against something like that anyway - so I am
either going to remove the requirement to differentitate between keypresses
and menu clicks from my application - or simply revert back to my old menu
items, avoiding the automatic generation of accelerator keys :o(,
Thanks for the help,
Mark.
···
Robin Dunn <robin@alldunn.com> wrote on 08/05/2003 12:41:51 PM:
> Argh! You're right of course.
>
> It does appear the event.this is always the same, however. And it also
> appears that it is different between the menu-generated event, and the
> keyboard generated one.
>
I don' think you can depend on that, or at least not on the value
staying the same between different runs of the app. You are seeing the
same values because the event object is being created at the same place
on the stack each time, but it *is* being created each time so if
anything happens to be pushed on the stack in different orders, or if
the program is loaded in a different place in memory, or a different
version of Python or wxPython is used, then the location encoded in
event.this will be different.
It's kind of hokey to code against something like that anyway - so I am
either going to remove the requirement to differentitate between keypresses
and menu clicks from my application - or simply revert back to my old menu
items, avoiding the automatic generation of accelerator keys :o(,
If you do so then you could use an wxAcceleratorTable that uses different IDs than the coresponding menu items, and then you can catch them in two different EVT_MENU handlers.
···
--
Robin Dunn
Software Craftsman http://wxPython.org Java give you jitters? Relax with wxPython!
>
> It's kind of hokey to code against something like that anyway - so I am
> either going to remove the requirement to differentitate between
keypresses
> and menu clicks from my application - or simply revert back to my old
menu
> items, avoiding the automatic generation of accelerator keys :o(,
>
If you do so then you could use an wxAcceleratorTable that uses
different IDs than the coresponding menu items, and then you can catch
them in two different EVT_MENU handlers.
Good idea... I implemented a wxAcceleratorTable for only the couple
commands that I need to know the source of on top of the new autogenerated
ones - and it seems the wxAcceleratorTable-issued event takes precedence
over the automatically generated one because that is the only event I get
(with the new ID) when the key is pressed. I'm not sure what's going on
behind the scenes with the automatic ones. I thought it generated an
AcceleratorTable for my wxFrame, but if it did you would think when I
called SetAcceleratorTable later for my new accelerator entries it would
blow away all other autogenerated key bindings - but it doesn't. They
happily coexist.
Anyway - it seems to work great and all of my extra key parsing code and
OnChar handler is now obsolete!
Thanks,
Mark.
···
Robin Dunn <robin@alldunn.com> wrote on 08/05/2003 01:40:18 PM: > Mark Melvin wrote: