Matplotlib与wxPython PopupMenu合作

时间:2013-01-31 02:55:51

标签: python user-interface matplotlib wxpython popupmenu

单击鼠标时,我想在matplotlib窗口内的wxPython图上显示上下文菜单。

不幸的是,在检测到点击后,会调用PopupMenu方法,但它既不返回也不显示弹出窗口。 (这是使用Windows 7主机的VirtualBox内部的Ubuntu 12.10中的库存Python。)

到目前为止,这是我的代码;我错过了什么?即如何让PopupMenu实际显示?

import wx
import numpy
import matplotlib
matplotlib.use('WXAgg')
from matplotlib.figure import Figure
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigCanvas
from wxPython.wx import *

class MatplotlibContext(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1, 'some title')
        self.panel = wx.Panel(self)
        self.fig = Figure()
        self.canvas = FigCanvas(self.panel, -1, self.fig)
        self.axes = self.fig.add_subplot(111)
        x = numpy.linspace(0, 6.28)
        y = numpy.sin(x)
        self.axes.plot(x, y)
        self.canvas.draw()
        self.canvas.mpl_connect('button_press_event', self.context_menu)        
        self.vbox = wx.BoxSizer(wx.VERTICAL)
        self.vbox.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
        self.panel.SetSizer(self.vbox)
        self.vbox.Fit(self)

    def context_menu(self, event):
        print 'in context_menu callback: clicked at (%g, %g)' % (event.x, event.y)
        menu = wxMenu()
        item_id = wxNewId()
        menu.Append(item_id, 'item') 
        wx.EVT_MENU(menu, item_id, self.callback)
        self.PopupMenu(menu, wx.Point(event.x, event.y))
        menu.Destroy()

    def callback(self, event):
        print 'menu selection: %r' % event.GetId()

app = wx.PySimpleApp()
app.frame = MatplotlibContext()
app.frame.Show()
app.MainLoop()

编辑2013-01-31 :更正了代码中的拼写错误。修订问题:

上面的代码不适用于我在VirtualBox中运行Ubuntu 12.10或直接安装12.04的两台不同的机器,但主要适用于运行12.10的第四台机器。我不知道为什么会有区别。

否则,我想我现在的问题是:

  • 如何解决上/下坐标问题? (如果我点击窗口顶部的某个距离,它会显示距离底部的距离。)
  • 如果我打开一个PopupMenu(并可选择关闭它),那么当主窗口关闭时,该过程不会终止。我该如何解决这个问题?

修改2013-10-02 :版本信息

对于其中一台不起作用的机器,我正在使用Python 2.7.4,Matplotlib 1.2.1和wx 2.8.12.1运行Ubuntu 13.04。

1 个答案:

答案 0 :(得分:1)

我发现有一件事是使用wxpython / matplotlib的某些组合(不确定哪些),你可以通过从matplotlib事件处理程序显示模态窗口对象来以某种方式锁定事件循环。问题是matplotlib FigureCanvas不会自动释放鼠标,因此在例如发生破坏时会发生破坏。模态对话框尝试在鼠标释放事件触发之前抓取输入

似乎有一个简单的解决方案,至少在我遇到的情况下。插入:

event.guiEvent.GetEventObject().ReleaseMouse()

在事件处理程序的开头。