【问题标题】:wxpython capture keyboard events in a wx.Framewxpython 在 wx.Frame 中捕获键盘事件
【发布时间】:2012-02-01 04:35:24
【问题描述】:

我正在尝试捕获在 wx.Frame 中发生的键盘事件,我希望以下代码能够捕获这些事件。但是,当我运行代码时,永远不会调用处理程序 OnKeyDown:

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_KEY_DOWN, self.OnKeyDown)
        self.Bind(wx.EVT_KEY_UP, self.OnKeyDown)
        self.Bind(wx.EVT_CHAR, self.OnKeyDown)
        self.SetFocus()
        self.Show(True)

    def OnKeyDown(self, event=None):
        log.debug("OnKeyDown event %s" % (event))

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

如果有人知道如何做到这一点,我将不胜感激。

【问题讨论】:

    标签: python wxpython wxwidgets


    【解决方案1】:

    我发现我可以在框架中添加一个面板,并且面板更容易接受键盘事件。

    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_KEY_DOWN, self.OnKeyDown)
            self.panel.Bind(wx.EVT_KEY_UP, self.OnKeyDown)
            self.panel.Bind(wx.EVT_CHAR, self.OnKeyDown)
            self.panel.SetFocus()
            self.Show(True)
    
        def OnKeyDown(self, event=None):
            print "Event!"
    
    if __name__ == "__main__":
        app = wx.App(False)
        gui = MainWindow(None, "test")
        app.MainLoop()
    

    【讨论】:

    • @joaquin:不确定 sensitivity 是否是最佳术语,但这是一个很好的答案。我在 Ubuntu 上遇到了同样的问题,无法使用 wx.Frame 捕获关键事件。添加wx.PanelSetFocus() 解决了这个问题。
    【解决方案2】:

    如果您使用 log.warning,您的代码就可以工作。

    log.warning("OnKeyDown event %s" % (event))
    

    日志记录级别为:

    Level    Value
    CRITICAL  50
    ERROR     40
    WARNING   30
    INFO      20
    DEBUG     10
    UNSET      0
    

    默认的日志记录级别是警告。仅生成级别高于默认值的日志。因此,在默认级别 (30) 下,log.infolog.debug 都不会产生任何输出。

    在 OP cmets 之后编辑:设置正确的日志记录级别可以使您的代码在带有 python 2.6 和 wxpython 2.8.11 和 2.8.12 的 winXP 32 位和 win7 64 位上完美运行。然而,由于某种我不知道的原因,该代码在 ubuntu 上不起作用。这种差异与 wxwidgets 在不同 SO 中的实现方式有关,但与日志记录无关。 正如您已经发现的那样,要让它在 ubuntu 中工作,它需要添加一个面板以及使用适当的日志记录级别。所以这行得通:

    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.Bind(wx.EVT_KEY_DOWN, self.KeyDown)
            self.Bind(wx.EVT_KEY_UP, self.KeyDown)
            self.Bind(wx.EVT_CHAR, self.KeyDown)
            self.panel.SetFocus()
    
        def KeyDown(self, event=None):
            logging.warning("OnKeyDown event %s" % (event))
    
    if __name__ == "__main__":
        app = wx.App(False)
        gui = MainWindow(None, "test")
        gui.Show()
        app.MainLoop()
    

    【讨论】:

    • 我尝试进行此更改,也尝试不使用日志包 - 只是打印。两种改变都没有奏效。
    • @Kevin,您的意思是您答案中的代码有效,而您的问题或我的答案中的代码无效,甚至消除了日志记录?您使用的是什么 SO、python 和 wxPython 版本?这是在 win7 和 winXP、python 2.6、wxpython 2.8.11 和 2.8.12 中测试的
    • 我使用的是 Ubuntu 11.04 64bit,看起来你已经推断出来了。所以这是一个基于操作系统的怪癖,但是将面板添加到框架中是一种简单的解决方法。
    猜你喜欢
    • 2015-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多