在wxPython中如何将EVT_KEY_DOWN事件绑定到整个窗口?

16 投票
2 回答
10688 浏览
提问于 2025-04-16 03:18

我可以很容易地把一个事件绑定到文本框上。问题是,我必须点击文本框内部才能“捕捉”到这个事件。我希望能够在主窗口有焦点的时候,随时捕捉到有人按下方向键的情况。

不工作:

 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)

我很确定我漏掉了什么简单的东西。不过我现在有点卡住了。

2 个回答

4

你可以使用 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)

在加速器表中,你需要用到按钮或小部件的 ID,按下按钮就会触发小部件的事件处理程序。

如果你没有想要触发事件的小部件,而是希望有一种“隐形”的小部件来绑定事件,那你可以这样做:

    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)

我会遍历想要绑定的按键,为它们创建新的小部件 ID。然后我用这些 ID 来绑定菜单项(也就是加速器键触发的内容),并在加速器表的元组列表中使用这些 ID。

21

可以试着绑定到 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()

撰写回答