【问题标题】:Matplotlib and wxPython PopupMenu cooperationMatplotlib 与 wxPython PopupMenu 合作
【发布时间】:2023-03-16 23:27:02
【问题描述】:

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

不幸的是,在检测到点击后,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。

【问题讨论】:

  • 您的代码适用于我在 Fedora 18 上使用 stock python 2.7.3;唯一的问题是菜单出现在错误的位置 - 而不是点击的位置。
  • 它也主要适用于 Windows 7。它会给出一些错误和警告,但会显示菜单。然而,Y 轴坐标似乎在图表内恢复了。
  • 我猜你应该修复坐标,它可能在你系统的窗口之外。还要在这里修正错字menu.Destory()
  • 尝试从 PopupMenu 调用中删除 wx.Point(event.x, event.y)。我从不使用它,它对我来说“自动”显示在正确的位置。如果我从您的代码中删除它,它会显示在正确的位置。
  • 感谢@Fenikso 发现错字。我已经尝试在两台机器上安装 VirtualBox,但无法让它在那里工作,但它确实可以直接安装,尽管这并不能真正证明 VirtualBox 是问题所在。我编辑了这个问题以解决另外两个剩余的问题:向上与向下以及过程寿命。

标签: python user-interface matplotlib wxpython popupmenu


【解决方案1】:

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

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

event.guiEvent.GetEventObject().ReleaseMouse()

在事件处理程序的开始处。

【讨论】:

  • 不走运。在至少一台不起作用的机器上(添加到问题中的版本),matplotlib 事件处理程序继续工作,随后的点击将触发对 context_menu 的调用,但对 PopupMenu 的调用永远不会显示弹出窗口并且永远不会返回。跨度>
猜你喜欢
  • 1970-01-01
  • 2012-06-21
  • 1970-01-01
  • 2013-11-22
  • 1970-01-01
  • 2011-09-23
  • 2023-03-17
  • 1970-01-01
  • 2017-11-21
相关资源
最近更新 更多