[wxPython] Global shortcuts without menu?

Hi wxPythonistas,

is there a trick to define a wxAcceleratorTable without a wxMenu under wxGTK?

My MainUI is wxFrame derived. I decided, to renounce a menubar for the sake
of UI space. On the other hand, I like quitting my programs with Ctrl-Q and
would like to extend it with certain accelerators. MainUI consists of several
UI Controls, seperated by splitter windows.

I got wxAcceleratorTable entries only working after a preceeding

self.SetMenuBar(self.mainmenu)

which draws the menubar (unfortunately, even with empty labels :wink:

EVT_CHAR on MainFrame doesn't catch them either.

Cheers,
  Hans-Peter

Example for Alt-x = Quit, Alt-h=Help:

acctbl = wxAcceleratorTable([(wxACCEL_ALT|wxACCEL_CTRL, ord('X'), exitID),\
                                 (wxACCEL_ALT|wxACCEL_CTRL, ord('H'),
helpID)])
self.SetAcceleratorTable(acctbl)
#self refers to the main frame

Hope that helps,
Horst

···

On Mon, 4 Mar 2002 09:37, Hans-Peter Jansen wrote:

Hi wxPythonistas,

is there a trick to define a wxAcceleratorTable without a wxMenu under
wxGTK?

My MainUI is wxFrame derived. I decided, to renounce a menubar for the
sake of UI space. On the other hand, I like quitting my programs with
Ctrl-Q and would like to extend it with certain accelerators. MainUI
consists of several UI Controls, seperated by splitter windows.

I got wxAcceleratorTable entries only working after a preceeding

self.SetMenuBar(self.mainmenu)

which draws the menubar (unfortunately, even with empty labels :wink:

EVT_CHAR on MainFrame doesn't catch them either.

Been there, done that, didn't work:

#!/usr/bin/env python

from wxPython.wx import *

[wxID_WXFRAME1] = map(lambda _init_ctrls: wxNewId(), range(1))

class wxFrame1(wxFrame):
    def _init_utils(self):
        pass

    def _init_ctrls(self, prnt):
        wxFrame.__init__(self, size = (708, 487), id = wxID_WXFRAME1,
             pos = (265, 182), title = 'wxFrame1', parent = prnt,
             name = '', style = wxDEFAULT_FRAME_STYLE)
        self._init_utils()

    def __init__(self, parent):
        self._init_ctrls(parent)
        exitID = wxNewId()
        aTable = wxAcceleratorTable([(wxACCEL_CTRL, ord('Q'), exitID)])
        self.SetAcceleratorTable(aTable)

class BoaApp(wxApp):
    def OnInit(self):
        self.main = wxFrame1(None)
        self.main.Show(true)
        self.SetTopWindow(self.main)
        return true

def main():
    application = BoaApp(0)
    application.MainLoop()

if __name__ == '__main__':
    main()

Cheers,
  Hans-Peter

···

On Monday, 4. March 2002 00:21, Horst Herb wrote:

On Mon, 4 Mar 2002 09:37, Hans-Peter Jansen wrote:
> Hi wxPythonistas,
>
> is there a trick to define a wxAcceleratorTable without a wxMenu under
> wxGTK?
>
> My MainUI is wxFrame derived. I decided, to renounce a menubar for the
> sake of UI space. On the other hand, I like quitting my programs with
> Ctrl-Q and would like to extend it with certain accelerators. MainUI
> consists of several UI Controls, seperated by splitter windows.
>
> I got wxAcceleratorTable entries only working after a preceeding
>
> self.SetMenuBar(self.mainmenu)
>
> which draws the menubar (unfortunately, even with empty labels :wink:
>
> EVT_CHAR on MainFrame doesn't catch them either.

Example for Alt-x = Quit, Alt-h=Help:

acctbl = wxAcceleratorTable([(wxACCEL_ALT|wxACCEL_CTRL, ord('X'), exitID),\
                                 (wxACCEL_ALT|wxACCEL_CTRL, ord('H'),
helpID)])
self.SetAcceleratorTable(acctbl)
#self refers to the main frame

Hope that helps,
Horst

> def __init__(self, parent):
> self._init_ctrls(parent)
> exitID = wxNewId()
> aTable = wxAcceleratorTable([(wxACCEL_CTRL, ord('Q'), exitID)])
> self.SetAcceleratorTable(aTable)

You are inheriting from wxFrame, but not initialising the base class -
could that be your problem?

Well, I created the test app with boa. Look in self._init_ctrl(),
the base class is initialized, there.

Here is another stripped down version to play with.
It should close on Ctrl-Q and ALT-X, but only ALT-F4 works.

Robin?

#!/usr/bin/env python

from wxPython.wx import *

class wxFrame1(wxFrame):
    def __init__(self, parent):
        wxFrame.__init__(self, parent, -1, title = 'testFrame',
                         style = wxDEFAULT_FRAME_STYLE)
        exitID = wxNewId()
        aTable = wxAcceleratorTable([(wxACCEL_CTRL, ord('Q'), exitID),
                                     (wxACCEL_ALT, ord('X'), exitID)])
        self.SetAcceleratorTable(aTable)

class BoaApp(wxApp):
    def OnInit(self):
        self.main = wxFrame1(None)
        self.main.Show(true)
        self.SetTopWindow(self.main)
        return true

def main():
    application = BoaApp(0)
    application.MainLoop()

if __name__ == '__main__':
    main()

For me, the solution I posted works flawless.

I can't see any logical difference in wxAcceleratorTable. Do you?

Horst

Cheers,
  Hans-Peter

···

On Monday, 4. March 2002 03:03, Horst Herb wrote:

On Mon, 4 Mar 2002 10:48, Hans-Peter Jansen wrote:

You still need to hook the event:

from wxPython.wx import *

[wxID_WXFRAME1] = map(lambda _init_ctrls: wxNewId(), range(1))

class wxFrame1(wxFrame):
    def _init_utils(self):
        pass

    def _init_ctrls(self, prnt):
        wxFrame.__init__(self, size = (708, 487), id = wxID_WXFRAME1,
             pos = (265, 182), title = 'wxFrame1', parent = prnt,
             name = '', style = wxDEFAULT_FRAME_STYLE)
        self._init_utils()

    def __init__(self, parent):
        self._init_ctrls(parent)
        exitID = wxNewId()
        aTable = wxAcceleratorTable([(wxACCEL_CTRL, ord('Q'), exitID)])
        self.SetAcceleratorTable(aTable)

        EVT_MENU(self, exitID, self.OnExit)

    def OnExit(self, evt):
        self.Close()

···

class BoaApp(wxApp):
    def OnInit(self):
        self.main = wxFrame1(None)
        self.main.Show(true)
        self.SetTopWindow(self.main)
        return true

def main():
    application = BoaApp(0)
    application.MainLoop()

if __name__ == '__main__':
    main()

--
Robin Dunn
Software Craftsman
robin@AllDunn.com Java give you jitters?
http://wxPython.org Relax with wxPython!

Unfortunately, this doesn't work within wxPython 2.3.2.1/wxGTK 2.3.2.

Does somebody with this environment would like to try,
if (s)he can close this app with Ctrl-Q and ALT-X:

#!/usr/bin/env python

from wxPython.wx import *

class wxFrame1(wxFrame):
    def __init__(self, parent):
        wxFrame.__init__(self, parent, -1, title = 'testFrame',
                         style = wxDEFAULT_FRAME_STYLE)
        exitID = wxNewId()
        aTable = wxAcceleratorTable([(wxACCEL_CTRL, ord('Q'), exitID),
                                     (wxACCEL_ALT, ord('X'), exitID)])
        self.SetAcceleratorTable(aTable)

        EVT_MENU(self, exitID, self.OnExit)

    def OnExit(self, evt):
        self.Close()

class BoaApp(wxApp):
    def OnInit(self):
        self.main = wxFrame1(None)
        self.main.Show(true)
        self.SetTopWindow(self.main)
        return true

def main():
    application = BoaApp(0)
    application.MainLoop()

if __name__ == '__main__':
    main()

Thanks for your patience.

Cheers,
  Hans-Peter

···

On Monday, 4. March 2002 19:05, Robin Dunn wrote:

You still need to hook the event:

        EVT_MENU(self, exitID, self.OnExit)

    def OnExit(self, evt):
        self.Close()

Shock and horror. Just discovered that the accelerator table in my own
program doesn't work either. The shortcuts I thought were working work
only because they are included in the menus too
(like self.filemenu.Append(exitID, 'E&xit\tAlt-X', 'Close it'))

So, I would appreciate hints regarding the accelerator tables too.

Horst

···

On Wed, 6 Mar 2002 04:31, Hans-Peter Jansen wrote:

On Monday, 4. March 2002 19:05, Robin Dunn wrote:
> You still need to hook the event:
>
> EVT_MENU(self, exitID, self.OnExit)
>
> def OnExit(self, evt):
> self.Close()

Unfortunately, this doesn't work within wxPython 2.3.2.1/wxGTK 2.3.2.

Does somebody with this environment would like to try,
if (s)he can close this app with Ctrl-Q and ALT-X:

I think there may be some more complicated interaction going on with how the
accelerators are handled. The PythonCard resourceEditor (in cvs) has a
number of bindings such as the one Horst describes below. I also tried just
setting the accelerator table directly. The resourceEditor window is a
wxPanel inside a wxFrame. When controls are added such as wxButton and
wxTextCtrl are added to the panel, those objects can be copied and pasted
via the clipboard to other layouts. When the app first starts up I can paste
using Ctrl+V, and do Cut and Copy. At some point, these bindings stop
working as controls are deleted from the panel. I'm still trying to figure
out a specific set of actions that cause the problem that can be repeated. I
think I've also seen some other acclerator bindings other than cut, copy,
and paste stop working while the app was running, but again I'm trying to
reproduce the behavior.

ka

···

-----Original Message-----
From: wxpython-users-admin@lists.wxwindows.org
[mailto:wxpython-users-admin@lists.wxwindows.org]On Behalf Of Horst Herb
Sent: Tuesday, March 05, 2002 1:44 PM
To: wxpython-users@lists.wxwindows.org
Subject: Re: [wxPython] Global shortcuts without menu? Still no go...

On Wed, 6 Mar 2002 04:31, Hans-Peter Jansen wrote:
> On Monday, 4. March 2002 19:05, Robin Dunn wrote:
> > You still need to hook the event:
> >
> > EVT_MENU(self, exitID, self.OnExit)
> >
> > def OnExit(self, evt):
> > self.Close()
>
> Unfortunately, this doesn't work within wxPython 2.3.2.1/wxGTK 2.3.2.
>
> Does somebody with this environment would like to try,
> if (s)he can close this app with Ctrl-Q and ALT-X:

Shock and horror. Just discovered that the accelerator table in my own
program doesn't work either. The shortcuts I thought were working work
only because they are included in the menus too
(like self.filemenu.Append(exitID, 'E&xit\tAlt-X', 'Close it'))

So, I would appreciate hints regarding the accelerator tables too.

Horst

I expect that it's a bug. Please enter a bug report at SF about it, and set
the category to wxGTK.

···

On Wed, 6 Mar 2002 04:31, Hans-Peter Jansen wrote:
> On Monday, 4. March 2002 19:05, Robin Dunn wrote:
> > You still need to hook the event:
> >
> > EVT_MENU(self, exitID, self.OnExit)
> >
> > def OnExit(self, evt):
> > self.Close()
>
> Unfortunately, this doesn't work within wxPython 2.3.2.1/wxGTK 2.3.2.
>
> Does somebody with this environment would like to try,
> if (s)he can close this app with Ctrl-Q and ALT-X:

Shock and horror. Just discovered that the accelerator table in my own
program doesn't work either. The shortcuts I thought were working work
only because they are included in the menus too
(like self.filemenu.Append(exitID, 'E&xit\tAlt-X', 'Close it'))

--
Robin Dunn
Software Craftsman
robin@AllDunn.com Java give you jitters?
http://wxPython.org Relax with wxPython!

Done.

https://sourceforge.net/tracker/index.php?func=detail&aid=526332&group_id=9863&atid=109863

Cheers,
  Hans-Peter

···

On Tuesday, 5. March 2002 23:07, Robin Dunn wrote:

> On Wed, 6 Mar 2002 04:31, Hans-Peter Jansen wrote:
> > On Monday, 4. March 2002 19:05, Robin Dunn wrote:
> > > You still need to hook the event:
> > >
> > > EVT_MENU(self, exitID, self.OnExit)
> > >
> > > def OnExit(self, evt):
> > > self.Close()
> >
> > Unfortunately, this doesn't work within wxPython 2.3.2.1/wxGTK 2.3.2.
> >
> > Does somebody with this environment would like to try,
> > if (s)he can close this app with Ctrl-Q and ALT-X:
>
> Shock and horror. Just discovered that the accelerator table in my own
> program doesn't work either. The shortcuts I thought were working work
> only because they are included in the menus too
> (like self.filemenu.Append(exitID, 'E&xit\tAlt-X', 'Close it'))

I expect that it's a bug. Please enter a bug report at SF about it, and
set the category to wxGTK.