回答編集履歴
5
解説!
test
CHANGED
@@ -4,9 +4,51 @@
|
|
4
4
|
|
5
5
|
|
6
6
|
|
7
|
+
■原因
|
8
|
+
|
9
|
+
`root.mainloop()` # ←の行でGUI入力待ちのブロッキングをしているからです。
|
10
|
+
|
11
|
+
そのため、`while`ループ内の`ret, frame = cap.read()`の行が実行されません。
|
12
|
+
|
13
|
+
参考:[Use TkInter without mainloop](https://gordonlesti.com/use-tkinter-without-mainloop/)
|
14
|
+
|
15
|
+
|
16
|
+
|
17
|
+
■対策
|
18
|
+
|
19
|
+
| | |
|
20
|
+
|
21
|
+
|:--|:--:|
|
22
|
+
|
23
|
+
|動画の処理を行う部分|cap.read()|
|
24
|
+
|
25
|
+
|tkinter表示部|root.mainloop()|
|
26
|
+
|
27
|
+
|
28
|
+
|
29
|
+
を分割してマルチスレッド/マルチプロセスで並列化すれば解消されるかと。
|
30
|
+
|
31
|
+
ここまでが、動画検知を行いながら+αの処理も行う方法
|
32
|
+
|
33
|
+
|
34
|
+
|
35
|
+
> Tkinterにて警告を出したい
|
36
|
+
|
37
|
+
|
38
|
+
|
39
|
+
そして、質問文のこの要件があるので、動画検知側から`tkinter`側に通知する必要があります。
|
40
|
+
|
41
|
+
そのために`multiprocessing#Queue`を使った、`producer-consumer`デザインパターンを使用しました。
|
42
|
+
|
43
|
+
|
44
|
+
|
45
|
+
---
|
46
|
+
|
47
|
+
|
48
|
+
|
7
49
|
あまり動作確認していませんが、サンプルコードを置いておきます。ご参考まで。
|
8
50
|
|
9
|
-
個人的には、プロセスを分けた方が良いのではとも。
|
51
|
+
個人的には、`python`のプロセスを分けた方が良いのではとも。
|
10
52
|
|
11
53
|
|
12
54
|
|
4
typoと初心者さんみたいなので、デザインパターン名を追加。
test
CHANGED
@@ -206,13 +206,15 @@
|
|
206
206
|
|
207
207
|
print(file_path)
|
208
208
|
|
209
|
+
※ producer-consumer デザインパターン
|
210
|
+
|
209
211
|
queue = Queue()
|
210
212
|
|
211
213
|
producer = Process(target=produce, args=(queue, file_path))
|
212
214
|
|
213
|
-
cu
|
215
|
+
consumer = Process(target=consume, args=(queue,))
|
214
|
-
|
216
|
+
|
215
|
-
cu
|
217
|
+
consumer.start() # ※ コンシューマから先に起動
|
216
218
|
|
217
219
|
producer.start()
|
218
220
|
|
3
ざっくばらんは方言みたいなので言葉を変更
test
CHANGED
File without changes
|
2
ざっくばらんは方言みたいなので言葉を変更
test
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
|
6
6
|
|
7
|
-
|
7
|
+
あまり動作確認していませんが、サンプルコードを置いておきます。ご参考まで。
|
8
8
|
|
9
9
|
個人的には、プロセスを分けた方が良いのではとも。
|
10
10
|
|
1
追記
test
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
やりたいことがあまり初心者向けとは思えないのですが、
|
2
2
|
|
3
|
-
multiprocessing
|
3
|
+
`multiprocessing`や`ProcessPoolExecutor`/`asyncio`でググるとサンプルソースがヒットするかもです。
|
4
4
|
|
5
5
|
|
6
6
|
|
@@ -50,7 +50,7 @@
|
|
50
50
|
|
51
51
|
ret, frame = capture.read()
|
52
52
|
|
53
|
-
if not ret: # readの戻り値は絶対に確認すること!!!!!!!!!!!
|
53
|
+
if not ret: # ※readの戻り値は絶対に確認すること!!!!!!!!!!!
|
54
54
|
|
55
55
|
break
|
56
56
|
|
@@ -104,6 +104,8 @@
|
|
104
104
|
|
105
105
|
print(wide) # , end=" ")
|
106
106
|
|
107
|
+
# ※ queueに追加 表示したい文字列なり数字なりEOF以外ならなんでも良い。
|
108
|
+
|
107
109
|
queue.put("attention!!!!")
|
108
110
|
|
109
111
|
else:
|
@@ -126,7 +128,7 @@
|
|
126
128
|
|
127
129
|
break
|
128
130
|
|
129
|
-
# EOF
|
131
|
+
# ※ EOF
|
130
132
|
|
131
133
|
queue.put(None)
|
132
134
|
|
@@ -140,13 +142,13 @@
|
|
140
142
|
|
141
143
|
def on_message(queue:Queue):
|
142
144
|
|
143
|
-
root.withdraw() # 非表示
|
145
|
+
root.withdraw() # ※ 非表示
|
144
|
-
|
146
|
+
|
145
|
-
item = queue.get(True) # タイムアウトを指定するかはどうかは仕様によるかと。
|
147
|
+
item = queue.get(True) # ※ タイムアウトを指定するかはどうかは仕様によるかと。
|
146
148
|
|
147
149
|
if not item: # EOF
|
148
150
|
|
149
|
-
# Windowの終了
|
151
|
+
# ※ Windowの終了
|
150
152
|
|
151
153
|
print("on_message EOF")
|
152
154
|
|
@@ -156,9 +158,9 @@
|
|
156
158
|
|
157
159
|
var_message.set(item)
|
158
160
|
|
159
|
-
root.deiconify() # 表示
|
161
|
+
root.deiconify() # ※ 表示
|
160
|
-
|
162
|
+
|
161
|
-
# デッドライン間隔、Queueに要素を追加するのが早いのならその点も考慮する事
|
163
|
+
# ※ デッドライン間隔、Queueに要素を追加するのが早いのならその点も考慮する事
|
162
164
|
|
163
165
|
root.after(1000, on_message, queue)
|
164
166
|
|
@@ -192,7 +194,7 @@
|
|
192
194
|
|
193
195
|
def main() -> None:
|
194
196
|
|
195
|
-
# ↓ファイル選択ダイアログでTopLevelウィンドウが表示されるので。
|
197
|
+
# ※ ↓ファイル選択ダイアログでTopLevelウィンドウが表示されるので。
|
196
198
|
|
197
199
|
root.withdraw()
|
198
200
|
|
@@ -210,11 +212,11 @@
|
|
210
212
|
|
211
213
|
customer = Process(target=consume, args=(queue,))
|
212
214
|
|
213
|
-
customer.start() # カスタマーから先に起動
|
215
|
+
customer.start() # ※ カスタマーから先に起動
|
214
216
|
|
215
217
|
producer.start()
|
216
218
|
|
217
|
-
producer.join() # プロデューサーはjoinで終了待ちを行う。
|
219
|
+
producer.join() # ※ プロデューサーはjoinで終了待ちを行う。
|
218
220
|
|
219
221
|
|
220
222
|
|