2012-01-03 139 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