2012-01-03 13 views
5

Estoy tratando de capturar los eventos del teclado que ocurren dentro de un wx.Frame, y esperaría que el siguiente código capturara esos eventos. Sin embargo, el manejador OnKeyDown nunca es llamado cuando corro el código:wxpython capturar eventos del teclado en un 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() 

Si alguien sabe cómo hacer esto, le agradecería un poco de ayuda.

Respuesta

3

Tu código funciona si usas log.warning.

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

Los niveles de registro son: nivel de registro

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

El valor predeterminado es de advertencia. Solo se generan registros con niveles superiores a los predeterminados. Por lo tanto, en el nivel predeterminado (30), ni log.info ni log.debug producen ningún resultado.

Editado después de los comentarios OP: Establecer el nivel correcto de registro hace que su código funcione perfectamente en winXP 32bit y win7 64bit con python 2.6 y wxpython 2.8.11 y 2.8.12. Sin embargo, el código no funciona en ubuntu por algún motivo que desconozco. Esta diferencia está relacionada con la forma en que wxwidgets se implementa en diferentes SO, pero no con el registro. Como ya descubrió, para que funcione en ubuntu, necesita agregar un panel así como el uso del nivel de registro adecuado. Entonces esto funciona:

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

Intenté hacer este cambio, y también traté de no usar el paquete de registro, simplemente imprima. Ningún cambio funcionó. – Kevin

+0

@Kevin, ¿quiere decir que el código en su respuesta funciona y el de su pregunta o mi respuesta no, incluso eliminando el registro? ¿Qué versiones de SO, python y wxPython estás usando? Esto se prueba en win7 y winXP, python 2.6, wxpython 2.8.11 y 2.8.12 – joaquin

+0

Estoy usando Ubuntu 11.04 64 bits, ya que parece que ya lo dedujo. Por lo tanto, es una peculiaridad basada en el SO, pero agregar el panel al marco es una solución fácil. – Kevin

6

Descubrí que puedo agregar un panel al marco, y un panel es mucho más receptivo a los eventos del teclado.

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: No estoy seguro si * sensitivity * es el mejor término, pero esta es una buena respuesta. Tuve el mismo problema en Ubuntu, no pude capturar eventos clave con un 'wx.Frame'. Agregar un 'wx.Panel' junto con un' SetFocus() 'solucionó el problema. – shinjin

Cuestiones relacionadas