问题描述
在我的项目中,我手动滚动了一个小对话框,可用于选择键和/或鼠标组合、“S”或“CTRL-SHIFT-C”或其他东西。我在 Linux 和 Windows 上都运行良好,但是当我在 Mac 上检查它时,对话框只会响应鼠标事件。
我把它归结为一个大约 30 行的最小示例,这实际上使它在 Linux 上以相同的方式被破坏,鼠标事件但没有键盘。在 Windows 上,我的最少代码按预期工作。
我看过演示代码,我觉得我在做他们正在做的事情,所以我很难过,尤其是在 Linux 上被破坏的简单代码。让关键事件可靠且跨平台地工作有什么神奇或秘诀吗?
import wx
class Main(wx.Frame):
def __init__(self,parent):
wx.Frame.__init__(self,parent,style=wx.WANTS_CHARS|wx.DEFAULT_FRAME_STYLE)
sizer = wx.BoxSizer(wx.VERTICAL);
desc = wx.StaticText( self,-1,"I receive mouse events but not kbd events")
sizer.Add( desc,1,wx.ALL,25);
for i in [self,desc]:
i.Bind(wx.EVT_CHAR_HOOK,self.OnKeyOrMouseEvt )
i.Bind(wx.EVT_CHAR,self.OnKeyOrMouseEvt )
i.Bind(wx.EVT_KEY_DOWN,self.OnKeyOrMouseEvt )
i.Bind(wx.EVT_KEY_UP,self.OnKeyOrMouseEvt )
i.Bind(wx.EVT_LEFT_DOWN,self.OnKeyOrMouseEvt )
i.Bind(wx.EVT_MIDDLE_DOWN,self.OnKeyOrMouseEvt )
i.Bind(wx.EVT_RIGHT_DOWN,self.OnKeyOrMouseEvt )
i.Bind(wx.EVT_MOUSE_AUX1_DOWN,self.OnKeyOrMouseEvt )
i.Bind(wx.EVT_MOUSE_AUX2_DOWN,self.OnKeyOrMouseEvt )
self.SetSizerAndFit(sizer);
def OnKeyOrMouseEvt(self,event):
print(f"I have received an event: {event}")
event.Skip()
if __name__ == "__main__":
app = wx.App()
main = Main(None)
main.Show()
app.MainLoop()
解决方法
我刚刚在 OSX 11.4 上运行了这个。适用于鼠标和按键事件。 OSX 上的重要部分(我怀疑 Linux 因为它比 Windows 更类似于 OSX)是父面板正在获得焦点和事件。此外,StaticText
无法获得焦点。
这是工作代码:
import wx
class Main(wx.Frame):
def __init__(self,parent):
wx.Frame.__init__(self,parent,style=wx.WANTS_CHARS|wx.DEFAULT_FRAME_STYLE)
panel = wx.Panel(self,wx.ID_ANY)
panel.Bind(wx.EVT_KEY_DOWN,self.on_mouse_key_event)
panel.Bind(wx.EVT_LEFT_DOWN,self.on_mouse_key_event)
def on_mouse_key_event(self,event):
print(f'{event}')
# Run the program
if __name__ == '__main__':
app = wx.App()
main = Main(None)
main.Show()
app.MainLoop()