回答編集履歴

5

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

2020/10/21 02:33

投稿

teamikl
teamikl

スコア8664

test CHANGED
@@ -128,10 +128,10 @@
128
128
 
129
129
 
130
130
 
131
- | | イベントループ | イベント処理 |
131
+ | | イベントループ | イベント処理 | ループ終了 |
132
132
 
133
- |-----|-----|-----|
133
+ |-----|-----|-----|----|
134
134
 
135
- | tkinter | mainloop | update_idletasks |
135
+ | tkinter | mainloop | update_idletasks | quit |
136
136
 
137
- | FigureCanvas | start_event_loop | flush_events |
137
+ | FigureCanvas | start_event_loop | flush_events | stop_event_loop |

4

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

2020/10/21 02:33

投稿

teamikl
teamikl

スコア8664

test CHANGED
@@ -112,7 +112,9 @@
112
112
 
113
113
 
114
114
 
115
- canvas.start_event_loop()を使う場合、matplotlib 側の作法でイベントループを終了します。
115
+ canvas.start_event_loop()を使う場合、
116
+
117
+ matplotlib 側の作法(stop_event_loop)でイベントループを終了します。
116
118
 
117
119
 
118
120
 

3

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

2020/10/21 02:32

投稿

teamikl
teamikl

スコア8664

test CHANGED
@@ -69,3 +69,67 @@
69
69
  何方が良いかについては、状況次第ですが
70
70
 
71
71
  上記で説明したoncmaskを呼び出す方法としては、こちらが適切でした。
72
+
73
+
74
+
75
+ ----
76
+
77
+ イベントループが混在すると面倒な点についての解説
78
+
79
+
80
+
81
+ ```python
82
+
83
+ canvas.start_event_loop()
84
+
85
+ # root.mainloop()
86
+
87
+ ```
88
+
89
+
90
+
91
+ NOTE: canvas.start_event_loop() を使う場合、
92
+
93
+
94
+
95
+ root.mainloop() は使えません (イベントループが競合) し不要になります。
96
+
97
+ FigureCanvasTkAgg 後の canvas.start_event_loop は
98
+
99
+ tkinter のイベントにも対応したイベントループになってます。
100
+
101
+
102
+
103
+ XXX: 但し、tkinter の幾つかのメソッドは想定通りに機能しない場合があります
104
+
105
+
106
+
107
+ 例えば、root.quit() は tkinter のイベントループ(mainloop)を終了するものなので
108
+
109
+ 通常のtkinterのプログラムでは、プログラムの終了として扱えますが、
110
+
111
+ tkinter のイベントループ(mainloop) を使っていないと機能しません。
112
+
113
+
114
+
115
+ canvas.start_event_loop()を使う場合、matplotlib 側の作法でイベントループを終了します。
116
+
117
+
118
+
119
+ この様に、どちらの方法を取るかによって参考に出来る情報が変わってきます。
120
+
121
+ イベントループの仕組みを知った上で扱うのであれば問題は少ないと思いますが、
122
+
123
+ そうでない場合、何処で問題が起きているのか解り難くなるので、注意点として書き残しておきます。
124
+
125
+
126
+
127
+
128
+
129
+ | | イベントループ | イベント処理 |
130
+
131
+ |-----|-----|-----|
132
+
133
+ | tkinter | mainloop | update_idletasks |
134
+
135
+ | FigureCanvas | start_event_loop | flush_events |

2

説明を追記

2020/10/21 02:07

投稿

teamikl
teamikl

スコア8664

test CHANGED
@@ -35,3 +35,37 @@
35
35
 
36
36
 
37
37
  ```
38
+
39
+
40
+
41
+ ----
42
+
43
+ 詳細
44
+
45
+
46
+
47
+ - 最初のコードは FigureCanvasTkAgg 以前に button_press_event を登録していました。
48
+
49
+ - FigureCanvasTkAgg により fig.canvas がtkinter 対応のものに置き換わります。
50
+
51
+ - tkinter 対応の canvas に button_press_event を登録
52
+
53
+ - ここでの canvas.start_event_loop は、FigureCanvasTkAgg により tk に対応した
54
+
55
+  tkinter と mpl_connect で登録したイベント両方に対応するイベントループ
56
+
57
+
58
+
59
+ こちらのアプローチでは逆で、
60
+
61
+ matplotlib 側のイベントループ内で、tkinter のイベント処理を行うために
62
+
63
+ 上記の説明で言う flush_events() 相当のモノ
64
+
65
+ (tkinterではupdate_idletasks()) を呼び出しています。
66
+
67
+
68
+
69
+ 何方が良いかについては、状況次第ですが
70
+
71
+ 上記で説明したoncmaskを呼び出す方法としては、こちらが適切でした。

1

文章修正

2020/10/21 01:44

投稿

teamikl
teamikl

スコア8664

test CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
 
4
4
 
5
- ポイントは、FigureCanvasTkAggの後に fig.canvas
5
+ ポイントは、FigureCanvasTkAggの後に fig.canvas.mpl_connect
6
6
 
7
7
  と root.mainloop() の代わりに canvas.start_event_loop()
8
8