0

I worked really hard understanding this, and it feels so darn close! I have a loop in which I create some wxpanels and attach them to notebook tabs. Each tab contains a plot. Originally the event call on the plot didn't pass the correct plot panel, so the event handling function reported the position for the wrong plot. I thought I would sort that out with a dict:

    self.plotdict ["plot" + str(plotcounter)] = wx.Panel(self, id=wx.ID_ANY)

then I was able to change my function so it passed the dict key rather than the plot, which I feel better with anyway.

    self.plotdict ["plot" + str(plotcounter)].canvas.mpl_connect('motion_notify_event', lambda event: self.cbUpdateCursor(event, ("plot" + str(plotcounter))))

however, even when this loop has run many times, and I have many plots in tabs, this line in the loop always sends the same key to the function self.cbUpdateCursor, as if it is only using the function call for the last tab/plot created.

        def cbUpdateCursor(self, event, plot):
    if event.inaxes:
        text = 'x = %5.4f, y = %5.4f' % (event.xdata, event.ydata)
        print text
        print plot
        print self.plotdict[plot]
        print id(self.plotdict [plot])
        self.plotdict [plot].cursor_pos.SetLabel(text)

this means that the print from the function (which is only there for testing), shows the same plot referece regardless of which tab and therefore which plot the mouse event occurd on.

  Print results for mouse over plot1
    x = -127.8006, y = 135.9350
    plot3
    <wx._windows.Panel; proxy of <Swig Object of type 'wxPanel *' at 0x2f63758> >
    52125616
  Print results for mouse over plot2
    x = -185.0618, y = 137.9096
    plot3
    <wx._windows.Panel; proxy of <Swig Object of type 'wxPanel *' at 0x2f63758> >
    52125616

why is my mouse event on my canvas calling the function associated with plot 3 regardless of which plot my mouse is on? (plot 3 in this case was the last one created).

BenMorel
  • 34,448
  • 50
  • 182
  • 322
Andrewb
  • 63
  • 1
  • 5

1 Answers1

1

I think your problem might be because you need to make a closure on your motion notify event functions. A couple of really good answers about closures can be found here.

Perhaps something like:

for plot_count in plot_counts:
    def update_plot(event, plot_count=plot_count):
        self.cbUpdateCursor(event, 'plot%s' % plot_count)

    self.plotdict['plot%s' % plot_count].canvas.mpl_connect('motion_notify_event', update_plot)

However, because you haven't provided a SSCCE I cannot test that this is actually the case.

Community
  • 1
  • 1
pelson
  • 21,252
  • 4
  • 92
  • 99
  • My code is messy at the moment; I am sorry you needed more. I have solved this problem one way, by "getting" the active page. `code`page = self.nb.GetPage(self.nb.GetSelection()) – Andrewb Aug 11 '12 at 22:48
  • Ok. So were you not able to test the result of my suggested change? – pelson Aug 12 '12 at 06:27
  • pelson, I think I'm doing the same thing. I just define my function once, outside of the loop. Any reason your's is in the loop? – Andrewb Aug 12 '12 at 14:20
  • Its hard to tell, but that is the point of this answer: If my answer is correct, then yes it does matter that the function is inside the loop. If you haven't already done so, I would highly recommend reading the question on closures that I linked to (http://stackoverflow.com/questions/233673/lexical-closures-in-python). – pelson Aug 12 '12 at 19:12