wxPython - 如何阻止wx.Control失去焦点在箭头键按?

问题描述:

import wx 

class Control(wx.Control): 

    def __init__(self, parent): 

     wx.Control.__init__(self, parent) 

     self.Bind(wx.EVT_CHAR, self.OnKey) 
     self.Bind(wx.EVT_KEY_DOWN, self.OnKey) 
     self.Bind(wx.EVT_KEY_DOWN, self.OnKey) 
     self.Bind(wx.EVT_LEFT_DOWN, self.OnMouseClick) 

    def OnKey(self, event): 
     print("key pressed") 
     event.Skip() 

    def OnMouseClick(self, event): 
     self.SetFocus() 
     print("has focus") 
     event.Skip() 

class Frame(wx.Frame): 

    def __init__(self, parent=None): 

     wx.Frame.__init__(self, parent) 

     panel = wx.Panel(self) 
     sizer = wx.BoxSizer(wx.HORIZONTAL) 
     radio = wx.RadioButton(panel, label="Radio button") 
     button = wx.Button(panel, label="Button") 
     control = Control(panel) 

     sizer.Add(radio, 0, wx.ALL, 5) 
     sizer.Add(button, 0, wx.ALL, 5) 
     sizer.Add(control, 0, wx.ALL, 5) 

     panel.SetSizer(sizer) 

     self.Show() 

if __name__ == "__main__": 
    app = wx.App() 
    frame = Frame() 
    app.MainLoop() 

一个非常简单的例子。wxPython - 如何阻止wx.Control失去焦点在箭头键按?

通过点击控件,设置焦点来控制。但是,即使将按键绑定到一个函数OnKey,按下方向键将焦点更改为另一个按钮/小部件。

有没有一种方法类似AcceptsFocusFromKeyboard(个体经营):

说明:可以在该窗口通过键盘导航给予重点是什么?如果不是的话,唯一让它专注的方法就是点击它。

除此之外,

一种方法,在我的控制不从键盘导航

你们俩的事件处理程序失去焦点缺少呼吁:

event.Skip() 

这些事件非wxCommandEvents,为了使它们正常工作,OS必须执行任何需要执行的操作。这就是Skip()的用途。否则,该事件将被控制器吃掉。

请检查该方法的文档,添加它,看看是否解决了这个问题。

另外,出于好奇,当用户按下箭头键时,你会发生什么?

如果您希望焦点在按下箭头键时保持不变,请尝试通过event.GetKeyCode()过滤事件(检查文档中正确的函数名称)并且不要调用event.Skip()这个案例。

如果这不起作用,请尝试捕获wx.EVT_CHAR_HOOK事件。

如果即使这样做不起作用,请重写FilterEvent()。

另外,你的GUI结构很怪异。尝试获取RAD工具(wxGlade,wxSmith等),在那里构建并查看结果。或者查看wxPython发行版中的演示文件夹(可作为不同的下载)来查看如何在wxPython中制作正常的布局。

也可以通过修复GUI来修复箭头键问题。

试试这个代码,而不是:

import wx 

class Frame(wx.Frame): 
    def __init__(self, parent=None): 
     wx.Frame.__init__(self, parent) 
     panel = wx.Panel(self) 
     sizer = wx.BoxSizer(wx.HORIZONTAL) 
     radio = wx.RadioButton(panel, label="Radio button") 
     button = wx.Button(panel, label="Button") 
     self.Bind(wx.EVT_CHAR, self.OnChar) 
     radio.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) 
     button.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) 
     self.Bind(wx.EVT_LEFT_DOWN, self.OnMouseClick) 

     sizer.Add(radio, 0, wx.ALL, 5) 
     sizer.Add(button, 0, wx.ALL, 5) 
     sizer.Add(control, 0, wx.ALL, 5) 

     panel.SetSizer(sizer) 

     self.Show() 

    def OnKeyDown(self, event): 
     print("key pressed") 
     if not event.GetKeyPress() == wx.WXK_LEFT_ARROW: # Check the function name. I'm writing from memory 
      event.Skip() 

    def OnChar(self, event): 
     print("Character key pressed on the panel") 
     event.Skip() 

    def OnMouseClick(self, event): 
     self.SetFocus() 
     print("has focus") 
     event.Skip() 

if __name__ == "__main__": 
    app = wx.App() 
    frame = Frame() 
    app.MainLoop() 

你应该明白我的意思。只有当按下的键不是箭头键时才调用event.Skip()。

+0

对不起,我没有测试event.Skip(),但我没有把它从例子中排除掉。我希望它能够专注于控件,方向键可以改变控件的状态。例如,像listctrl一样,箭头键可以更改列表中的选择,而不是从listctrl中失去焦点。 – Blackboard

+0

@Blackboard,答案已更新。 – Igor

+0

谢谢,我会尝试你所提出的建议。如果你不介意我问,代码(不是指间距或命名约定等)对你来说看起来是错误还是奇怪?我已经看到了很多以这种方式构建的各种教程的代码示例。(虽然我会检查更多的代码示例) – Blackboard