2012-01-03 138 views
5

我试图捕获发生在wx.Frame内部的键盘事件,并且我期望以下代码捕获这些事件。wxpython捕获wx.Frame中的键盘事件

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

如果有人知道如何做到这一点,我将不胜感激一些帮助:然而,当我运行代码的处理器的onkeydown永远不会被调用。

回答

3

如果您使用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注释后编辑:设置正确的日志记录级别使您的代码在python 2.6和wxpython 2.8.11和2.8.12的winXP 32bit和win7 64bit上完美工作。但是,由于某些原因我不知道该代码在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() 
+1

我试着做这个改变,也尝试不使用日志包 - 只是打印。这两个变化都没有奏效 – Kevin 2012-01-11 07:21:59

+0

@Kevin,你的意思是你的答案中的代码有效,而你的问题或答案中的代码不会,甚至消除了日志记录?你使用的是什么SO,Python和wxPython版本?这在win7和winXP,python 2.6,wxpython 2.8.11和2.8.12中测试过 – joaquin 2012-01-11 13:10:39

+0

我使用的是Ubuntu 11.04 64bit,因为它看起来像你已经推导出来的。所以这是一个基于操作系统的怪癖,但将面板添加到框架是一个简单的解决方法。 – Kevin 2012-01-12 00:27:19

6

我发现我可以在面板上添加一个面板,面板更容易接受键盘事件。

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

@joaquin:不知道*敏感*是最好的术语,但这是一个很好的答案。我在Ubuntu上遇到了同样的问题,无法使用'wx.Frame'来捕获关键事件。在其上添加'wx.Panel'和'SetFocus()'解决了这个问题。 – shinjin 2014-10-20 03:08:57