2012-01-03 5 views
5

Я пытаюсь захватить события клавиатуры, которые происходят внутри wx.Frame, и я ожидал бы следующий код для захвата этих событий. Однако обработчик OnKeyDown никогда не вызывается, когда я запускаю код: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() 

Если кто-нибудь знает, как это сделать, я был бы признателен за помощь.

ответ

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.info или log.debug не производит никакого выхода.

Отредактировано после комментариев OP: Настройка правильного уровня ведения журнала делает ваш код идеальным для работы на winXP 32bit и win7 64bit с помощью python 2.6 и wxpython 2.8.11 и 2.8.12. Код, однако, не работает на 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

+0

@ Kevin, вы имеете в виду, что код в вашем ответе работает, а тот, что есть в вашем вопросе или мой ответ, нет, даже устраняя ведение журнала? Какие версии SO, python и wxPython вы используете? Это проверено в win7 и winXP, python 2.6, wxpython 2.8.11 и 2.8.12 – joaquin

+0

Я использую Ubuntu 11.04 64bit, поскольку он выглядит так, как вы уже вывели. Так что это причуда, основанная на ОС, но добавление панели в рамку - это простое решение. – Kevin

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

Смежные вопросы