В wxPython как вы привязываете событие EVT_KEY_DOWN ко всему окну?

Я могу связать событие с текстовым полем np. Проблема в том, что я должен щелкнуть внутри поля textctrl, чтобы "поймать" это событие. Я надеюсь, что когда-нибудь кто-то нажимает клавиши со стрелками, а главное окно имеет фокус.

НЕ РАБОТАЕТ:

 wx.EVT_KEY_DOWN(self, self.OnKeyDown)

РАБОЧИЕ:

self.NudgeTxt = wx.TextCtrl(self.panel, size=(40,20), value=str(5))
wx.EVT_KEY_DOWN(self.NudgeTxt, self.OnKeyDown)

Я уверен, что мне не хватает чего-то легкого. Однако я немного застрял.

Ответы

Ответ 1

Вместо этого попробуйте привязку к wx.EVT_CHAR_HOOK

например..

self.Bind(wx.EVT_CHAR_HOOK, self.onKey)

  ...

def onKey(self, evt):
    if evt.GetKeyCode() == wx.WXK_DOWN:
        print "Down key pressed"
    else:
        evt.Skip()

Ответ 2

Вы можете использовать EVT_CHAR_HOOK,

    self.Bind(wx.EVT_CHAR_HOOK, self.hotkey)


def hotkey(self, event):
    code = event.GetKeyCode()
    if code == wx.WXK_LEFT:  # or whatever...
        ...

или используйте таблицу ускорителей

    ac = [(wx.ACCEL_NORMAL, wx.WXK_LEFT, widget.GetId())]
    tbl = wx.AcceleratorTable(ac)
    self.SetAcceleratorTable(tbl)

вам нужно будет использовать кнопку или идентификатор виджетов в таблице ускорителей, а нажатие этой кнопки вызывает обработчик событий виджетов.

Если у вас нет виджетов, которые вы хотели бы активировать для их событий, и предпочли бы какой-то "невидимый" виджет с привязками событий, вы можете сделать это:

    ac = []
    keys = [wx.WXK_LEFT, wx.WXK_RIGHT, wx.WXK_UP, wx.WXK_DOWN]
    for key in keys:
        _id = wx.NewId()
        ac.append((wx.ACCEL_NORMAL, key, _id))
        self.Bind(wx.EVT_MENU, self.your_function_to_call, id=_id)

    tbl = wx.AcceleratorTable(ac)
    self.SetAcceleratorTable(tbl)

Я перебираю нужные ключи для привязки и создаю для них новые идентификаторы виджетов. Затем я использую эти идентификаторы для привязки элементов меню (какие триггеры ускорителя запускаются) и используйте эти идентификаторы в списке таблиц ускорителей.