質問するログイン新規登録

回答編集履歴

5

ループの終了方法を表に追記

2020/10/21 02:33

投稿

teamikl
teamikl

スコア8824

answer CHANGED
@@ -63,7 +63,7 @@
63
63
  そうでない場合、何処で問題が起きているのか解り難くなるので、注意点として書き残しておきます。
64
64
 
65
65
 
66
- | | イベントループ | イベント処理 |
66
+ | | イベントループ | イベント処理 | ループ終了 |
67
- |-----|-----|-----|
67
+ |-----|-----|-----|----|
68
- | tkinter | mainloop | update_idletasks |
68
+ | tkinter | mainloop | update_idletasks | quit |
69
- | FigureCanvas | start_event_loop | flush_events |
69
+ | FigureCanvas | start_event_loop | flush_events | stop_event_loop |

4

matplotlib側の作法について具体的なメソッド(stop_event_loop)を追記

2020/10/21 02:33

投稿

teamikl
teamikl

スコア8824

answer CHANGED
@@ -55,7 +55,8 @@
55
55
  通常のtkinterのプログラムでは、プログラムの終了として扱えますが、
56
56
  tkinter のイベントループ(mainloop) を使っていないと機能しません。
57
57
 
58
- canvas.start_event_loop()を使う場合、matplotlib 側の作法でイベントループを終了します。
58
+ canvas.start_event_loop()を使う場合、
59
+ matplotlib 側の作法(stop_event_loop)でイベントループを終了します。
59
60
 
60
61
  この様に、どちらの方法を取るかによって参考に出来る情報が変わってきます。
61
62
  イベントループの仕組みを知った上で扱うのであれば問題は少ないと思いますが、

3

注意点:イベントループが混在すると面倒な点についての解説

2020/10/21 02:32

投稿

teamikl
teamikl

スコア8824

answer CHANGED
@@ -33,4 +33,36 @@
33
33
  (tkinterではupdate_idletasks()) を呼び出しています。
34
34
 
35
35
  何方が良いかについては、状況次第ですが
36
- 上記で説明したoncmaskを呼び出す方法としては、こちらが適切でした。
36
+ 上記で説明したoncmaskを呼び出す方法としては、こちらが適切でした。
37
+
38
+ ----
39
+ イベントループが混在すると面倒な点についての解説
40
+
41
+ ```python
42
+ canvas.start_event_loop()
43
+ # root.mainloop()
44
+ ```
45
+
46
+ NOTE: canvas.start_event_loop() を使う場合、
47
+
48
+ root.mainloop() は使えません (イベントループが競合) し不要になります。
49
+ FigureCanvasTkAgg 後の canvas.start_event_loop は
50
+ tkinter のイベントにも対応したイベントループになってます。
51
+
52
+ XXX: 但し、tkinter の幾つかのメソッドは想定通りに機能しない場合があります
53
+
54
+ 例えば、root.quit() は tkinter のイベントループ(mainloop)を終了するものなので
55
+ 通常のtkinterのプログラムでは、プログラムの終了として扱えますが、
56
+ tkinter のイベントループ(mainloop) を使っていないと機能しません。
57
+
58
+ canvas.start_event_loop()を使う場合、matplotlib 側の作法でイベントループを終了します。
59
+
60
+ この様に、どちらの方法を取るかによって参考に出来る情報が変わってきます。
61
+ イベントループの仕組みを知った上で扱うのであれば問題は少ないと思いますが、
62
+ そうでない場合、何処で問題が起きているのか解り難くなるので、注意点として書き残しておきます。
63
+
64
+
65
+ | | イベントループ | イベント処理 |
66
+ |-----|-----|-----|
67
+ | tkinter | mainloop | update_idletasks |
68
+ | FigureCanvas | start_event_loop | flush_events |

2

説明を追記

2020/10/21 02:07

投稿

teamikl
teamikl

スコア8824

answer CHANGED
@@ -16,4 +16,21 @@
16
16
 
17
17
  # root.mainloop()
18
18
 
19
- ```
19
+ ```
20
+
21
+ ----
22
+ 詳細
23
+
24
+ - 最初のコードは FigureCanvasTkAgg 以前に button_press_event を登録していました。
25
+ - FigureCanvasTkAgg により fig.canvas がtkinter 対応のものに置き換わります。
26
+ - tkinter 対応の canvas に button_press_event を登録
27
+ - ここでの canvas.start_event_loop は、FigureCanvasTkAgg により tk に対応した
28
+  tkinter と mpl_connect で登録したイベント両方に対応するイベントループ
29
+
30
+ こちらのアプローチでは逆で、
31
+ matplotlib 側のイベントループ内で、tkinter のイベント処理を行うために
32
+ 上記の説明で言う flush_events() 相当のモノ
33
+ (tkinterではupdate_idletasks()) を呼び出しています。
34
+
35
+ 何方が良いかについては、状況次第ですが
36
+ 上記で説明したoncmaskを呼び出す方法としては、こちらが適切でした。

1

文章修正

2020/10/21 01:44

投稿

teamikl
teamikl

スコア8824

answer CHANGED
@@ -1,6 +1,6 @@
1
1
  後から思いついたのだけど、こちらの方が変更点少なくて良いかもしれません。
2
2
 
3
- ポイントは、FigureCanvasTkAggの後に fig.canvas
3
+ ポイントは、FigureCanvasTkAggの後に fig.canvas.mpl_connect
4
4
  と root.mainloop() の代わりに canvas.start_event_loop()
5
5
 
6
6