0

我正在开发一个 WX-MPL 应用程序,以根据用户输入显示和交互式处理数据。我在设置 MPL 鼠标事件以在 WX 应用程序中工作时遇到困难。

目标是拥有一系列可编辑的垂直线,描绘在早期处理中识别的特征的开始和结束时间。用户应该能够沿 x 轴拖动线条、删除不需要的线条并插入新线条。

到目前为止,我已经能够使用标准的 MPL 图(我认为它的 Tk)来实现这个功能。当我尝试将这些类集成到我的应用程序中时,事件处理出现了一些问题,我无法与线对象交互或创建新的线对象。所以我备份了一个步骤,并一直试图在我的工作示例中增加复杂性,以确定问题出现在哪里。

将工作示例作为简单的 WX 应用程序运行时,NewVLineListener 类似乎不再接收 button_press_events。以下是与我遇到的特定问题相关的代码。

这是我第一次处理鼠标事件,我肯定遗漏了一些东西……任何建议将不胜感激。

另外,我正在运行 WX 2.8.12 和 MPL 1.1.1rc。

from matplotlib.figure import Figure
import wx
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg

class NewVLineListener:
    global castLog, count, dvls, ax1
    lock = None  # only one can be animated at a time
    def __init__(self, fig):
        self.fig = fig

    def connect(self):
        'connect to all the events we need'
        self.cidpressright = self.fig.canvas.mpl_connect(
        'button_press_event', self.on_press_right)

    def on_press_right(self, event):
        global count, castLog, dvls, ax1
        print event.button
        if event.button != 3: return
        tag = 'Begin'
        # Increase castLog Key to accomodate new Vline
        count += 1
        print 'count: ', count
        # Set castLog values to x-value of triggering event
        castLog[str(count)] = { tag:event.xdata }
        # Spawn a new DraggableVline instance
        color_map = {'Begin':'g', 'End':'r'}
        dvl = DraggableVline(self.fig, ax1.axvline(x=castLog[str(count)][tag], linewidth=2, color=color_map[tag]), count, tag)
        dvl.connect()
        dvls.append(dvl)

        canvas = self.fig.canvas
        canvas.draw()

class MainFrame(wx.Frame):
        def __init__(self):
            wx.Frame.__init__(self, None, wx.ID_ANY)
            global castLog, count, ax1, dvls
            fig = Figure()
            canvas = FigureCanvasWxAgg(self, -1, fig)
            ax1 = fig.add_subplot(111)

            # Create empty dict that will hold new V-line Data
            castLog = { } 
            dvls = [ ]
            count = 0

            # Instantiate New Vline Listener
            NVL = NewVLineListener(fig)
            NVL.connect()

if __name__ == '__main__':
        app = wx.PySimpleApp()
        app.frame = MainFrame()
        app.frame.Show()
        app.MainLoop()
4

1 回答 1

1

我知道了!

我认为对 NewVlineListener 对象的引用正在被垃圾收集,因此从未收到过事件。通过将 NVL 对象引用添加到对可拖动的 vline 对象的引用数组中,它会保持并按预期接收事件。

class MainFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY)
        global castLog, count, ax1, dvls
        fig = Figure()
        canvas = FigureCanvasWxAgg(self, -1, fig)
        ax1 = fig.add_subplot(111)

        # Create empty dict that will hold new V-line Data
        castLog = { } 
        dvls = [ ]
        count = 0

        # Instantiate New Vline Listener
        NVL = NewVLineListener(fig)
        NVL.connect()
        dvls.append(NVL) # This keeps NVL reference from being garbage collected?

我仍然觉得有趣的是,命名 NewVlineListener 对象不足以保留引用,并且它适用于 pyplot 但现在适用于 wx,但这似乎有效。

于 2013-07-30T03:32:01.363 回答