2012-01-03 40 views
5

Próbuję przechwytywać zdarzenia klawiatury, które występują wewnątrz ramki wx.Frame, i oczekiwałbym następującego kodu, aby uchwycić te zdarzenia. Jednak obsługi onKeyDown nigdy nie jest wywoływana, gdy uruchamiam kod:Zdarzenia klawiatury przechwytywania wxpython w pliku 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() 

Jeśli ktoś wie jak to zrobić, będę wdzięczny za pomoc.

Odpowiedz

3

Twój kod działa, jeśli używasz log.warning.

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

Poziomy rejestrowania są:

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

Domyślny poziom rejestrowania się ostrzeżenie. Wykonuje się tylko dzienniki o poziomach wyższych niż domyślne. Tak więc, na poziomie domyślnym (30), ani log.info ani log.debug nie dają żadnego wyjścia.

Edytowany po komentarzach OP: Ustawienie prawidłowego poziomu rejestrowania powoduje, że kod działa idealnie na winXP 32bit i win7 64bit z pythonem 2.6 i wxpythonem 2.8.11 i 2.8.12. Kod jednak nie działa na Ubuntu z jakiegoś powodu, którego nie znam. Ta różnica jest związana z tym, w jaki sposób wxwidgets jest zaimplementowany w różnych SO, ale nie w logowaniu. Jak już odkryłeś, aby działał w Ubuntu, potrzebny jest panel, który zostanie dodany, oraz użycie odpowiedniego poziomu logowania. To działa:

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

Próbowałem dokonać tej zmiany, a także starałem się nie używać pakietu logowania - wystarczy wydrukować. Żadna zmiana nie zadziałała. – Kevin

+0

@Kevin, masz na myśli kod w twojej odpowiedzi działa, a ten w twoim pytaniu lub mojej odpowiedzi nie, nawet eliminując logowanie? Które wersje SO, python i wxPython używasz?. To jest testowane w win7 i winXP, python 2.6, wxpython 2.8.11 i 2.8.12 – joaquin

+0

Używam Ubuntu 11.04 64bit, ponieważ wygląda na to, że już wydedukowałeś. Jest to więc dziwactwo oparte na systemie operacyjnym, ale dodanie panelu do ramki jest łatwe w obsłudze. – Kevin

6

Pomyślałem, że mogę dodać panel do ramki, a panel jest znacznie bardziej otwarty na zdarzenia na klawiaturze.

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: Nie jestem pewien, czy * wrażliwość * jest najlepszym terminem, ale jest to dobra odpowiedź. Miałem ten sam problem w Ubuntu, nie mogłem uchwycić kluczowych zdarzeń za pomocą 'wx.Frame'. Dodanie 'wx.Panel' wraz z' SetFocus() 'rozwiązało problem. – shinjin

Powiązane problemy