我正在编写一个将 matplotlib 图合并到 wxPython GUI 中的程序。我希望能够区分一些绘图元素上的简单单击、选项单击、命令单击等(以便根据单击绘图元素时按下的键来执行不同的操作)。
我的代码如下:
将 matplotlib“pick_event”绑定到处理程序:
self.figure.canvas.mpl_connect('pick_event', self.onClick)
在处理程序中,检查哪个/是否按下了任何键
def onClick(self, event): """handle clicking on different objects in the plotarea""" ## get relevant event data ## ... other stuff here ... pressedKey = None pressedKey = event.mouseevent.key ## key pressed while clicking print "You pressed key '%s' while clicking!" % pressedKey ## ... more stuff here ... if pressedKey == "alt+alt": self.onOptionClick(...)
...然后继续其他功能
然而,我的问题是 matplotlib 作为按下的键返回的内容是完全错误的。
例如,当我打开程序、绘制数据、单击点(没有按下任何键)时,我不断收到“您在单击时按下了键 'ctrl+control'!”。如果我在数据点上单击选项,则无论我是否按下选项键,这都会变为永久“单击时您按下了键 'alt+alt'!”。只有当我通过命令单击数据点后,它才会返回正确的“单击时您按下了‘无’键!” 简单的点击。
(更不用说pressedKey的返回非常不直观:如果我只是按一个“Alt/Option”键,为什么要“alt+alt”?为什么要使用“ctrl+control”作为命令?)
能够区分不同类型的点击对于我的程序的正确运行非常重要。
更新#1:
哦亲爱的。这越来越令人困惑。我下面的示例代码运行良好,我的主程序仍然没有。这怎么可能?此外,我下面的小示例确实在“无”响应和“”响应之间交替进行简单点击。(我无法复制它;目前它只给我“无”响应 - 即“你在点击时按下了‘无’键!”)
这是示例代码:
#!/bin/usr/env python
import wx
import matplotlib as mpl
mpl.use('WXAgg')
from matplotlib.figure import Figure as mplFigure
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as mplCanvas
class PlotPanel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
self.figure = mplFigure(figsize=(9, 6))
self.ax = self.figure.add_subplot(111)
self.ax.plot([1, 2, 3, 4], [2, 3, 5, 8], marker="o", markersize=20, picker=10, linestyle="None")
self.canvas = mplCanvas(self, -1, self.figure)
self.figure.canvas.mpl_connect('pick_event', self.onClick)
def onClick(self, event):
pressedKey = None
pressedKey = event.mouseevent.key ## key pressed while clicking
print "You pressed key '%s' while clicking!" % pressedKey
class MainFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1, "matplotlib pick_event problem")
self.plotarea = PlotPanel(self)
self.mainSizer = wx.BoxSizer(wx.HORIZONTAL)
self.mainSizer.Add(self.plotarea, 1, wx.EXPAND)
self.SetSizer(self.mainSizer)
self.mainSizer.Fit(self)
if __name__ == "__main__":
app = wx.App(False)
mainFrame = MainFrame()
mainFrame.Show()
app.MainLoop()
更新#2:
好的,所以问题似乎是我的处理程序有时会打开其他窗口,并且密钥释放事件在这些窗口中“丢失”。也就是说,matplotlib 永远不会知道有问题的键已被释放,所以在下一次单击时,即使没有按下键,它仍然给人的印象是该键被按下。如果您将上面的处理程序更改为
def onClick(self, event):
pressedKey = None
pressedKey = event.mouseevent.key ## key pressed while clicking
wx.MessageBox("You pressed key '%s' while clicking!" % pressedKey)
它实际上重现了问题。
所以我想我的问题现在变成了:我如何(手动)告诉 matplotlib 密钥已被释放?“event.Skip()”不工作;蟒蛇告诉我
"PickEvent instance has no attribute 'Skip'"