Wx Matplotlib事件处理

时间:2013-07-27 15:08:35

标签: event-handling matplotlib wxpython

我正在开发一个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()

1 个答案:

答案 0 :(得分: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,但是这似乎有效。