Search code examples
pythoneventswxpythonkeyboard-events

wxpython don't capture EVT_HELP


I have a little problem, I am using FreeBSD but this problem occurs on linux as well.

I try to send an wx.EVT_HELP by the use of the key F1, but nothing happens:

import logging as log
import wx

class MainWindow(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, title=title, size=(200,100))

        self.Bind(wx.EVT_HELP, self.function)
        self.SetFocus()
        self.Show(True)

    def function(self, event=None):
        print "drin"

if __name__ == "__main__":
    app = wx.App(False)
    gui = MainWindow(None, "test")
    app.MainLoop()

I tried it with a panel like in wxpython can't capture EVT_KEY_DOWN enent

import logging as log
import wx

class MainWindow(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, title=title, size=(200,100))

        self.panel = wx.Panel(self, wx.ID_ANY)
        self.panel.Bind(wx.EVT_HELP, self.function)
        self.panel.SetFocus()
        self.Show(True)

    def function(self, event=None):
        print "drin"

if __name__ == "__main__":
    app = wx.App(False)
    gui = MainWindow(None, "test")
    app.MainLoop()

but this didn't work either (and I would want to prevent panels in my case). The only possibilities I know is to use wx.EVT_KEY_DOWN with panels or wx.CHAR_HOOK (works without panels) but in both cases they bind every keyevent to my function and I want just F1 or rather the wx.EVT_HELP.

Do someone know how I can connect F1 with wx.EVT_HELP, so that my first code would work?

Thanks for your time!


Thanks for your help! The AcceleratorTable is something I was looking for! But I don't get why there is a need for a panel, my testcode

import logging as log
import wx

class MainWindow(wx.Frame):
    def __init__(self, parent, title):

        wx.Frame.__init__(self, parent, title=title, size=(200,100))
        wx.Panel(self, wx.ID_ANY)
        f1_id = wx.NewId()
        self.Bind(wx.EVT_MENU, self.function, id = f1_id)
        accel_tbl = wx.AcceleratorTable([(wx.ACCEL_NORMAL, wx.WXK_F1, f1_id)])
        self.SetAcceleratorTable(accel_tbl)
        self.SetFocus()
        self.Show(True)

    def function(self, event=None):
        print "drin"

if __name__ == "__main__":
    app = wx.App(False)
    gui = MainWindow(None, "test")
    app.MainLoop()

works but it isn't even using the panel. Is there a possibility to work around a panel? Or is a frame (with unix) not sensitive enough to receive the keyevents? (When I delete the panel in my testcode it works with no key.)


Solution

  • You need to use a wx.AcceleratorTable. Here's a simple example:

    import logging as log
    import wx
    
    class MainWindow(wx.Frame):
        def __init__(self, parent, title):
            wx.Frame.__init__(self, parent, title=title, size=(200,100))
    
            self.panel = wx.Panel(self, wx.ID_ANY)
            self.panel.Bind(wx.EVT_HELP, self.function)
    
            f1_id = wx.NewId()
            self.Bind(wx.EVT_MENU, self.function, id=f1_id)
            accel_tbl = wx.AcceleratorTable([(wx.ACCEL_NORMAL, wx.WXK_F1, f1_id )])
            self.SetAcceleratorTable(accel_tbl)
    
            self.Show(True)
    
        def function(self, event=None):
            print "drin"
    
    if __name__ == "__main__":
        app = wx.App(False)
        gui = MainWindow(None, "test")
        app.MainLoop()
    

    This worked for me with wxPython 3.0.2. Classic on Xubuntu 16.04 with Python 2.7.12

    For more information on the topic: