回答編集履歴

3

改善例を追記

2021/10/14 12:13

投稿

teamikl
teamikl

スコア8664

test CHANGED
@@ -53,6 +53,68 @@
53
53
  - root.title の部分を print に変更すると、GUIへのアクセスは発生しない為、エラーは起こりません。
54
54
 
55
55
  - daemon スレッドにする場合も同様ですが、タイミング次第では起こる可能性は残ります(意図的な再現は難しい)
56
+
57
+
58
+
59
+ 上で提示したコードの改善例
60
+
61
+ ```python
62
+
63
+ from threading import Thread, Event
64
+
65
+ import tkinter as tk
66
+
67
+
68
+
69
+ def worker(root, event):
70
+
71
+ for num, _ in enumerate(range(5), start=1):
72
+
73
+ print(num)
74
+
75
+ if event.is_set():
76
+
77
+ break
78
+
79
+ root.title(f"{num}")
80
+
81
+ # NOTE: time.sleep では、メインスレッドで thread.join 時に GUIがフリーズする為、
82
+
83
+ # 中断可能な Event.wait を利用。
84
+
85
+ event.wait(1)
86
+
87
+
88
+
89
+ root = tk.Tk()
90
+
91
+ event = Event()
92
+
93
+ event.clear()
94
+
95
+ thread = Thread(target=worker, args=(root, event))
96
+
97
+
98
+
99
+ def on_close():
100
+
101
+ event.set() # 修了を通知
102
+
103
+ thread.join() # workerの完了を待つ
104
+
105
+ root.destroy() # GUIの破棄 (ウィンドウを閉じる)
106
+
107
+ root.protocol("WM_DELETE_WINDOW", on_close)
108
+
109
+
110
+
111
+ root.after(1000*1, thread.start)
112
+
113
+ root.after(1000*3, on_close)
114
+
115
+ root.mainloop()
116
+
117
+ ```
56
118
 
57
119
 
58
120
 

2

問題点の追記

2021/10/14 12:13

投稿

teamikl
teamikl

スコア8664

test CHANGED
@@ -1,4 +1,66 @@
1
+ 問題点: サブスレッドからのGUIの直接操作
2
+
3
+
4
+
5
+ メインスレッド終了後(GUIが破棄された後) に、サブスレッドがGUIにアクセスする事になる為、
6
+
7
+ 問題が起こります。
8
+
1
- デーモンスレッドを使わない場合暫定的な回避策
9
+ デーモンスレッドの場合(その他の子スレッドがない場合)サブスレッドも終了される為
10
+
11
+ 問題が発生しません。
12
+
13
+
14
+
15
+ 意図的に同じ問題を起こすコード
16
+
17
+ ```python
18
+
19
+ from threading import Thread
20
+
21
+ import tkinter as tk
22
+
23
+
24
+
25
+ def worker(root):
26
+
27
+ import time
28
+
29
+ for num in range(5):
30
+
31
+ root.title(f"{num}")
32
+
33
+ time.sleep(1)
34
+
35
+
36
+
37
+ root = tk.Tk()
38
+
39
+ thread = Thread(target=worker, args=(root,))
40
+
41
+
42
+
43
+ root.after(1000*1, thread.start) # 1秒後に開始
44
+
45
+ root.after(1000*3, root.quit) # 3秒後にGUIを終了
46
+
47
+ root.mainloop()
48
+
49
+ ```
50
+
51
+
52
+
53
+ - root.title の部分を print に変更すると、GUIへのアクセスは発生しない為、エラーは起こりません。
54
+
55
+ - daemon スレッドにする場合も同様ですが、タイミング次第では起こる可能性は残ります(意図的な再現は難しい)
56
+
57
+
58
+
59
+
60
+
61
+ ----
62
+
63
+ 暫定的な回避策
2
64
 
3
65
 
4
66
 

1

書式の修正

2021/10/14 12:04

投稿

teamikl
teamikl

スコア8664

test CHANGED
@@ -1,13 +1,3 @@
1
- 問題個所は特定されいて、
2
-
3
- デーモンスレッドにするという回避策も見出されているようなので、
4
-
5
- その他の方法の
6
-
7
-
8
-
9
- ----
10
-
11
1
  デーモンスレッドを使わない場合の、暫定的な回避策
12
2
 
13
3