問題点:
root = tk.Tk(), plt.show() 内部でも初期化される
root.mainloop(), plt.show() どちらもイベント待機するループ。
解決策:
「埋め込む方法でマウスイベントを使う」が順当な方法です。
他の回避策:
tkinter/matplotlib どちらかのイベントループで双方を稼働させる。
matplotlib のバックエンドを tkagg にして、
tkinterの新しいウィンドウを作るのは Toplevel を使ってみてください。
python
1# 事前にバックエンドを設定
2import matplotlib
3matplotlib.use('TkAgg')
4
5# root = tk.Tk() は figure 内で行われているので、キャンバス経由で参照
6root = fig.canvas.get_tk_widget().master
7
8window = tk.Toplevel(root)
9window.title("tk window")
10tk.Label(window, text="test").pack()
11tk.Button(window, text="Close this window", command=window.destroy).pack()
12tk.Button(window, text="Close this app", command=root.destroy).pack()
13
14
15# この後に plt.show() を呼び出し ... 内部で mainloop() が呼ばれる
幾つか注意点があります。
root = tk.Tk() と plt.show() を同時に使うのはお勧めしません。
plt.show() 内部で tk.Tk() が呼び出される為、 訂正: figure 生成時でした
2重に初期化が行われてしまいます。
但し、tkinter のウィジェット生成は、
tk.Tk() が呼ばれた後でないといけないので、
plt.show() 内部で呼び出されるタイマーイベントで、
tkinter のウィンドウを作るという回避策を取ります。
(matplotlib のイベントには詳しくないので、
ここは他により良い呼び出し方があるかもしれません)
追記: コードを変更
マルチスレッドでは、(matplotlibのバックエンドがtkの場合)
tkinter の初期化が2重に行われてしまうので、トラブルの元になります。
参考:
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。