回答編集履歴
2
Event.wait を使ったサンプルを削除。誤誘導になる為 / 追記: 2つのスレッドで実装
answer
CHANGED
@@ -31,42 +31,33 @@
|
|
31
31
|
→ tkinterでキー入力を拾い、別スレッドへ通知
|
32
32
|
|
33
33
|
----
|
34
|
-
ボタンによる別スレッドの停止のデモ (threading.Event の使い方サンプル)
|
35
|
-
```python
|
36
|
-
import tkinter as tk
|
37
|
-
|
34
|
+
解説: 2つのスレッドで実装する
|
38
|
-
import time
|
39
35
|
|
36
|
+
問題点:
|
37
|
+
Lockで排他制御する場合、GUI等のイベント駆動プログラミングでは
|
38
|
+
ロック獲得によるブロックが発生すると、ウィンドウのフリーズに繋がる為、
|
39
|
+
避ける傾向があります。
|
40
40
|
|
41
|
-
|
41
|
+
解決策: 代案としては、プログラムの構造自体を
|
42
|
-
# スライドショーの代替として
|
43
|
-
while True:
|
44
|
-
|
42
|
+
リソース毎に担当のスレッドを決めて、そのリソースは担当のスレッドからしか操作しないように、
|
45
|
-
|
43
|
+
もし外部から操作したい場合は、queue 等を用いてスレッド間の通信で行う、とします。
|
46
|
-
|
44
|
+
今回のケースであれば、対象のリソースは tkinter と cv2 の2つに別ける。
|
47
45
|
|
48
|
-
|
46
|
+

|
49
|
-
pause.set()
|
50
47
|
|
48
|
+
起動時
|
49
|
+
- Sub(cv2): 準備後に、tkinter起動を待機 `tk_started.wait()`
|
50
|
+
- Main(tk): tkinter を起動
|
51
|
+
- Main(tk): イベントループを開始。tk_started.set() で Subスレッドの待機を解除
|
52
|
+
- Sub(cv2): イベントループ開始。スライドショー
|
51
53
|
|
52
|
-
|
54
|
+
停止処理
|
53
|
-
|
55
|
+
- Main(tk): shared.pause = True
|
56
|
+
- Sub(cv2): c2.waitKey(1) を呼び続けるループに入る(イベントループ継続の為)
|
54
57
|
|
55
|
-
|
58
|
+
終了処理
|
56
|
-
|
59
|
+
- Main(tk): shared.running = sharead.pause = False (停止状態解除と稼働フラグをオフに)
|
57
|
-
|
60
|
+
- Sub(cv2): フラグがオフになったことにより、イベントループを抜けて終了
|
58
|
-
pause.clear()
|
59
|
-
else:
|
60
|
-
e.widget.config(text="stop")
|
61
|
-
pause.set()
|
62
61
|
|
63
|
-
|
62
|
+
----
|
64
|
-
|
63
|
+
訂正: ~~ボタンによる別スレッドの停止のデモ (threading.Event の使い方サンプル)~~
|
65
|
-
button.bind("<Button-1>", click)
|
66
|
-
button.pack()
|
67
|
-
root.after_idle(thread.start)
|
68
|
-
root.mainloop()
|
69
|
-
```
|
70
|
-
|
71
|
-
注意: event.wait() はイベントループ内では使わない事。
|
72
|
-
マウス・キー入力が処理できなくてウィンドウがフリーズします。
|
1
補足
answer
CHANGED
@@ -28,7 +28,7 @@
|
|
28
28
|
※ cv2 のバックエンド次第では、メインスレッドで使わないといけないような制限がある事もあるかもしれません。
|
29
29
|
その場合は、tkinterをサブスレッドで使うか、マルチプロセスにする。
|
30
30
|
- cv2.waitKey 等は入力所得が競合する為、何らかの対策が必要です。
|
31
|
-
→ tkinterでキー入力を拾い、別スレッドへ
|
31
|
+
→ tkinterでキー入力を拾い、別スレッドへ通知
|
32
32
|
|
33
33
|
----
|
34
34
|
ボタンによる別スレッドの停止のデモ (threading.Event の使い方サンプル)
|
@@ -66,4 +66,7 @@
|
|
66
66
|
button.pack()
|
67
67
|
root.after_idle(thread.start)
|
68
68
|
root.mainloop()
|
69
|
-
```
|
69
|
+
```
|
70
|
+
|
71
|
+
注意: event.wait() はイベントループ内では使わない事。
|
72
|
+
マウス・キー入力が処理できなくてウィンドウがフリーズします。
|