当用户在OSX上按下COMMAND + [任何其他键]时,我正试图捕获一个事件。由于这些实际上是两次按键,我期待两个事件:一个是按下COMMAND,一个是按下另一个按键(不释放COMMAND键)。这适用于除COMMAND之外的每个修饰符,其中我只获得第一个事件。为什么这样,我该如何解决?
版本:wxPython3.0-osx-cocoa-py2.7
示例代码:
import wx
def OnKeyDown(e):
print "Modifiers: {} Key Code: {}".format(e.GetModifiers(), e.GetKeyCode())
app = wx.App()
frame = wx.Frame(None)
textctrl = wx.TextCtrl(frame, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, wx.WANTS_CHARS)
textctrl.Bind(wx.EVT_KEY_DOWN, OnKeyDown)
frame.Show()
app.MainLoop()
对于ALT + d,输出为:
Modifiers: 1 Key Code: 307
Modifiers: 1 Key Code: 68
对于SHIFT + d,输出为:
Modifiers: 4 Key Code: 306
Modifiers: 4 Key Code: 68
仅对于COMMAND + d,输出为:
Modifiers: 2 Key Code: 308
感谢您的帮助
其他信息:我在虚拟机上使用OSX 10.8 。正如RobinDunn指出它可以在他的笔记本电脑上运行。所以很有可能这只是我环境中的一个问题。 wnnmaw提供了一个很好的解决方法,即使在虚拟环境中也适用于我。
答案 0 :(得分:0)
好吧,所以我花了一些时间,但这是一个可以完成你想要的工作代码块。
有些注意事项:
wx.ACCEL_RAW_CTRL
的支持,该支持对应于Mac上的实际控制键,而wx.ACCCEL_CTRL
对应于命令键没有进一步的说法,这里是
import wx
from wx.lib.scrolledpanel import ScrolledPanel
class TestWindow(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1, 'Accelerator Table Test', size=(600, 400))
self.panel = ScrolledPanel(parent=self, id=-1)
self.panel.SetupScrolling()
#Create IDs to be used in initial acclerator table
self.functionList = [self.func1, self.func2, self.func3, self.func4, self.func5, self.OnAdd, self.OnDel]
self.functionListstr = ["self.func1", "self.func2", "self.func3", "self.func4", "self.func5", "self.OnAdd", "self.OnDel"]
self.IDDict = {i: wx.NewId() for i in range(len(self.functionList))}
self.IDDictrev = {val:key for key, val in self.IDDict.iteritems()}
self.aTableList = [(wx.ACCEL_ALT, ord('S'), self.IDDict[0]),(wx.ACCEL_CTRL, ord('Q'), self.IDDict[1])]
#Set up initial accelerator table
aTable = wx.AcceleratorTable(self.aTableList)
self.SetAcceleratorTable(aTable)
#Bind inital accelerator table IDs to functions
for i in range(len(self.functionList)):
self.Bind(wx.EVT_MENU, self.functionList[i], id=self.IDDict[i])
#Set up control widgets on GUI
self.flexgrid = wx.FlexGridSizer(cols=3, hgap=10, vgap=5)
cmdkeylbl = wx.StaticText(self.panel, -1, "Command Key")
self.cmdkey = wx.ComboBox(self.panel, style=wx.CB_READONLY)
cmdkeylist = ["Alt", "Control/Command", "Shift", "OSX Control", "None"]
self.cmdkeyconstants = {"Alt":wx.ACCEL_ALT, "Control/Command":wx.ACCEL_CTRL, "Shift":wx.ACCEL_SHIFT, "None":wx.ACCEL_NORMAL}
self.cmdkeyconstantsrev = {val:key for key, val in self.cmdkeyconstants.iteritems()}
self.cmdkey.SetItems(cmdkeylist)
hotkeylbl = wx.StaticText(self.panel, -1, "HotKey (single letter only)")
self.hotkey = wx.TextCtrl(self.panel, size=(50,-1))
funclbl = wx.StaticText(self.panel, -1, "Function")
self.func = wx.ComboBox(self.panel, style=wx.CB_READONLY)
self.func.SetItems(self.functionListstr)
self.hbox = wx.BoxSizer(wx.HORIZONTAL)
addBtn = wx.Button(self.panel, -1, "Add")
delBtn = wx.Button(self.panel, -1, "Delete")
self.Bind(wx.EVT_BUTTON, self.OnAdd, addBtn)
self.Bind(wx.EVT_BUTTON, self.OnDel, delBtn)
self.vbox = wx.BoxSizer(wx.VERTICAL)
self.curATable = wx.StaticText(self.panel, -1, self._DisplayATable())
self.flexgrid.Add(cmdkeylbl)
self.flexgrid.Add(hotkeylbl)
self.flexgrid.Add(funclbl)
self.flexgrid.Add(self.cmdkey)
self.flexgrid.Add(self.hotkey)
self.flexgrid.Add(self.func)
self.hbox.Add((20, 20), 0)
self.hbox.Add(addBtn)
self.hbox.Add((0, 0), 0)
self.hbox.Add(delBtn)
self.hbox.Add((20, 20), 0)
self.vbox.Add(self.flexgrid, flag=wx.TOP|wx.BOTTOM|wx.LEFT|wx.RIGHT|wx.EXPAND, border = 5)
self.vbox.Add(self.hbox, flag=wx.TOP|wx.BOTTOM|wx.LEFT|wx.RIGHT|wx.EXPAND, border = 5)
self.vbox.Add(self.curATable, flag=wx.TOP|wx.BOTTOM|wx.LEFT|wx.RIGHT|wx.EXPAND, border = 5)
self.panel.SetSizer(self.vbox)
self.panel.Layout()
#Class Functions
def _DisplayATable(self):
aTablelbl = ""
for cmdKey, hotKey, Func in self.aTableList:
aTablelbl += "{} + {} calls {}\n".format(self.cmdkeyconstantsrev[cmdKey], chr(hotKey), self.functionListstr[self.IDDictrev[Func]])
return aTablelbl
def OnAdd(self, event):
self.aTableList.append((self.cmdkeyconstants[self.cmdkey.GetValue()], ord(self.hotkey.GetValue()[:1].title()), self.IDDict[self.func.GetSelection()]))
print "Added {} + {} as a shortcut for {}!".format(self.cmdkey.GetValue(), self.hotkey.GetValue()[:1].title(), self.functionListstr[self.func.GetSelection()])
aTable = wx.AcceleratorTable(self.aTableList)
self.SetAcceleratorTable(aTable)
self.curATable.SetLabel(self._DisplayATable())
self.panel.Layout()
def OnDel(self, event):
if (self.cmdkeyconstants[self.cmdkey.GetValue()], ord(self.hotkey.GetValue()[:1].title()), self.IDDict[self.func.GetSelection()]) in self.aTableList:
self.aTableList.remove((self.cmdkeyconstants[self.cmdkey.GetValue()], ord(self.hotkey.GetValue()[:1].title()), self.IDDict[self.func.GetSelection()]))
aTable = wx.AcceleratorTable(self.aTableList)
self.SetAcceleratorTable(aTable)
self.curATable.SetLabel(self._DisplayATable())
self.panel.Layout()
else:
dlg = wx.MessageDialog(self, "ERROR: That combination is not in the accelerator table!", "Error", style=wx.OK)
dlg.ShowModal()
dlg.Destroy()
def func1(self, event):
dlg = wx.MessageDialog(self, "Func1", "Func1", style=wx.OK)
dlg.ShowModal()
dlg.Destroy()
def func2(self, event):
dlg = wx.MessageDialog(self, "Func2", "Func2", style=wx.OK)
dlg.ShowModal()
dlg.Destroy()
def func3(self, event):
dlg = wx.MessageDialog(self, "Func3", "Func3", style=wx.OK)
dlg.ShowModal()
dlg.Destroy()
def func4(self, event):
dlg = wx.MessageDialog(self, "Func4", "Func4", style=wx.OK)
dlg.ShowModal()
dlg.Destroy()
def func5(self, event):
dlg = wx.MessageDialog(self, "Func5", "Func5", style=wx.OK)
dlg.ShowModal()
dlg.Destroy()
app = wx.App(False)
frame = TestWindow()
frame.Show()
app.MainLoop()
希望这是您正在寻找的,如果您有任何问题,请告诉我