2016-08-24 78 views
1

我遇到了windows和mac如何處理python tk窗口和matplotlib圖close_event之間真正煩人的區別。matplotlib圖在tk應用程序內部觸發close事件後不會繼續執行程序流程

我的問題是這樣,

  1. 我試圖加載從TK按鈕事件matplotlib身影。
  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!這確實按預期工作。將使用此解決方案進行進一步的測試。 –