回答編集履歴
2
Event.wait を使ったサンプルを削除。誤誘導になる為 / 追記: 2つのスレッドで実装
test
CHANGED
@@ -64,80 +64,62 @@
|
|
64
64
|
|
65
65
|
----
|
66
66
|
|
67
|
-
ボタンによる別スレッドの停止のデモ (threading.Event の使い方サンプル)
|
68
|
-
|
69
|
-
```python
|
70
|
-
|
71
|
-
import tkinter as tk
|
72
|
-
|
73
|
-
|
67
|
+
解説: 2つのスレッドで実装する
|
74
|
-
|
75
|
-
import time
|
76
68
|
|
77
69
|
|
78
70
|
|
71
|
+
問題点:
|
79
72
|
|
73
|
+
Lockで排他制御する場合、GUI等のイベント駆動プログラミングでは
|
80
74
|
|
81
|
-
|
75
|
+
ロック獲得によるブロックが発生すると、ウィンドウのフリーズに繋がる為、
|
82
76
|
|
83
|
-
# スライドショーの代替として
|
84
|
-
|
85
|
-
|
77
|
+
避ける傾向があります。
|
86
|
-
|
87
|
-
event.wait() # ボタンが押されるとここで止る / もう一度で再開
|
88
|
-
|
89
|
-
print("tick") # ループが稼働しているのを確認する為に表示
|
90
|
-
|
91
|
-
time.sleep(0.5)
|
92
78
|
|
93
79
|
|
94
80
|
|
95
|
-
|
81
|
+
解決策: 代案としては、プログラムの構造自体を
|
96
82
|
|
83
|
+
リソース毎に担当のスレッドを決めて、そのリソースは担当のスレッドからしか操作しないように、
|
84
|
+
|
97
|
-
|
85
|
+
もし外部から操作したい場合は、queue 等を用いてスレッド間の通信で行う、とします。
|
86
|
+
|
87
|
+
今回のケースであれば、対象のリソースは tkinter と cv2 の2つに別ける。
|
98
88
|
|
99
89
|
|
100
90
|
|
101
|
-
|
102
|
-
|
103
|
-
thread = threading.Thread(
|
104
|
-
|
105
|
-
|
91
|
+
![イメージ説明](f8d72b3b9b2159caddabae3c56e70d4f.png)
|
106
92
|
|
107
93
|
|
108
94
|
|
109
|
-
|
95
|
+
起動時
|
110
96
|
|
111
|
-
|
97
|
+
- Sub(cv2): 準備後に、tkinter起動を待機 `tk_started.wait()`
|
112
98
|
|
113
|
-
|
99
|
+
- Main(tk): tkinter を起動
|
114
100
|
|
115
|
-
|
101
|
+
- Main(tk): イベントループを開始。tk_started.set() で Subスレッドの待機を解除
|
116
102
|
|
117
|
-
else:
|
118
|
-
|
119
|
-
|
103
|
+
- Sub(cv2): イベントループ開始。スライドショー
|
120
|
-
|
121
|
-
pause.set()
|
122
104
|
|
123
105
|
|
124
106
|
|
125
|
-
|
107
|
+
停止処理
|
126
108
|
|
127
|
-
|
109
|
+
- Main(tk): shared.pause = True
|
128
110
|
|
129
|
-
|
111
|
+
- Sub(cv2): c2.waitKey(1) を呼び続けるループに入る(イベントループ継続の為)
|
130
|
-
|
131
|
-
button.pack()
|
132
|
-
|
133
|
-
root.after_idle(thread.start)
|
134
|
-
|
135
|
-
root.mainloop()
|
136
|
-
|
137
|
-
```
|
138
112
|
|
139
113
|
|
140
114
|
|
141
|
-
|
115
|
+
終了処理
|
142
116
|
|
117
|
+
- Main(tk): shared.running = sharead.pause = False (停止状態解除と稼働フラグをオフに)
|
118
|
+
|
143
|
-
|
119
|
+
- Sub(cv2): フラグがオフになったことにより、イベントループを抜けて終了
|
120
|
+
|
121
|
+
|
122
|
+
|
123
|
+
----
|
124
|
+
|
125
|
+
訂正: ~~ボタンによる別スレッドの停止のデモ (threading.Event の使い方サンプル)~~
|
1
補足
test
CHANGED
@@ -58,7 +58,7 @@
|
|
58
58
|
|
59
59
|
- cv2.waitKey 等は入力所得が競合する為、何らかの対策が必要です。
|
60
60
|
|
61
|
-
→ tkinterでキー入力を拾い、別スレッドへ
|
61
|
+
→ tkinterでキー入力を拾い、別スレッドへ通知
|
62
62
|
|
63
63
|
|
64
64
|
|
@@ -135,3 +135,9 @@
|
|
135
135
|
root.mainloop()
|
136
136
|
|
137
137
|
```
|
138
|
+
|
139
|
+
|
140
|
+
|
141
|
+
注意: event.wait() はイベントループ内では使わない事。
|
142
|
+
|
143
|
+
マウス・キー入力が処理できなくてウィンドウがフリーズします。
|