0

私はこれを理解するために一生懸命働きました。いくつかの wxpanels を作成してノートブックのタブにアタッチするループがあります。各タブにはプロットが含まれています。もともと、プロットのイベント呼び出しは正しいプロット パネルを渡さなかったため、イベント処理関数は間違ったプロットの位置を報告していました。私は辞書でそれを整理すると思った:

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

その後、関数を変更して、プロットではなくdictキーを渡すことができました。とにかく気分が良くなりました。

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

ただし、このループが何度も実行され、タブに多くのプロットがある場合でも、ループ内のこの行は、最後のタブの関数呼び出しのみを使用しているかのように、常に同じキーを関数 self.cbUpdateCursor に送信します/プロットが作成されました。

        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)

これは、関数からの出力 (テストのためだけにあります) が、どのタブに関係なく同じプロット参照を示していることを意味し、したがって、マウス イベントが発生したプロットは同じです。

  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

キャンバス上のマウス イベントが、マウスがオンになっているプロットに関係なく、プロット 3 に関連付けられた関数を呼び出すのはなぜですか? (この場合のプロット 3 は最後に作成されたものです)。

4

1 に答える 1

1

モーション通知イベント関数を閉じる必要があるため、問題が発生する可能性があると思います。クロージャーに関する非常に優れた回答がいくつかここにあります。

おそらく次のようなものです:

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)

ただし、SSCCEを提供していないため、これが実際に当てはまるかどうかをテストできません。

于 2012-08-11T18:33:36.837 に答える