2016-08-24 1 views
1

windowsとmacがpython tkウィンドウとmatplotlib figure close_eventをどのように扱うのか、本当に面倒な違いに遭遇しました。matplotlib figureはtkアプリケーションの中でトリガーされたcloseイベントの後にプログラムフローを続行しません

私の問題は、私はTkのボタンイベントからmatplotlibのフィギュアをロードしようとしています、これ

  1. です。
  2. 図が表示され、 プロットがアクティブな間にtk UIプログラムフローをブロックし、プロットが になるまでユーザイベントをキャプチャします。
  3. プロットが閉じられた後、tkアプリは続行する必要があります。

問題の最小限のアプリが問題を示しています。

from Tkinter import * 
from matplotlib import pyplot as plt 


class Plotter: 
    def __init__(self): 
     self.fig = plt.figure() 
     self.fig.canvas.mpl_connect('close_event', self.dispose) 

     plt.plot(1, 2, 'r*') 
     plt.show() 
     print "done with plotter" 

    def dispose(self, event): 
     plt.close('all') 
     print "disposed" 


if __name__ == '__main__': 
    def pressed(): 
     print 'button pressed' 
     Plotter() 
     print 'YAY' 

    root = Tk() 
    button = Button(root, text='Press', command=pressed) 
    button.pack(pady=20, padx=20) 

    root.mainloop() 

悲しいことに、私はpython2.7、matplotlibの(1.5.2)の同じバージョンを使ってMac上のウィンドウではなく、期待通り、この作品を発見しました。 これは良いUIの習慣ではありませんが、このコードではMacとWindowsに違いがあることが気になります。私はこの問題に役立つフィードバックをいただければ幸いです。その間、非ブロッキングスレッドでプロッタを実装し、閉じたときにメインアプリケーションに結果を戻す作業を開始します。

答えて

1

plt.ion()を使用してMatplotlibの対話モードをオンにすることはできますが、それだけでフローをブロックすることなくプログラムが続行されます。手動でフローをブロックするには、self.fig.canvas.start_event_loop_default()self.fig.canvas.stop_event_loop()を使用して、イベントがキャプチャされるまでプログラムフローを一時停止します。あなたの最小限の例で実装

from Tkinter import * 
from matplotlib import pyplot as plt 

class Plotter: 
    def __init__(self): 
     plt.ion() 
     self.fig = plt.figure() 
     self.fig.canvas.mpl_connect('close_event', self.dispose) 
     self.fig.canvas.mpl_connect('button_press_event', self.on_mouse_click) 

     plt.plot(1, 2, 'r*') 
     plt.show() 
     self.fig.canvas.start_event_loop_default() 
     print "done with plotter" 

    def dispose(self, event): 
     self.fig.canvas.stop_event_loop() 
     print "disposed" 

    def on_mouse_click(self, event): 
     print 'mouse clicked!' 


if __name__ == '__main__': 
    def pressed(): 
     print 'button pressed' 
     Plotter() 
     print 'YAY' 

root = Tk() 
button = Button(root, text='Press', command=pressed) 
button.pack(pady=20, padx=20) 

root.mainloop() 
+0

おかげで@nemo!これは実際に期待どおりに動作します。このソリューションでさらにテストを行います。 –

関連する問題