質問編集履歴

1

あああああ

2018/10/03 11:41

投稿

flan
flan

スコア146

test CHANGED
File without changes
test CHANGED
@@ -1,3 +1,181 @@
1
+ ### 追記
2
+
3
+ ご指摘ありがとうございます。
4
+
5
+ 修正後のコードと、原因が何となく分かったので追記します。
6
+
7
+ [参考にしたstackoverflow
8
+
9
+ ](https://stackoverflow.com/questions/27073762/tcl-asyncdelete-error-multithreading-python)で挙げられいていた質問を読み返したらこのようなことが書いてありました。
10
+
11
+
12
+
13
+ This occurs because you created the Tk main window on a thread and you don't have the UI running on the processes main thread
14
+
15
+ (tkinterのウィジェットはメインスレッド以外で作成してはならない)
16
+
17
+
18
+
19
+ もし作成した場合
20
+
21
+
22
+
23
+ When you exit the process the cleanup is being done from the process primary thread
24
+
25
+ (そのプロセスを削除する)
26
+
27
+
28
+
29
+ みたいです。つまりメインスレッドtk()からtk.loop()以外でウィジェットを作成してはならないということでしょうかね・・
30
+
31
+ これは非常に困った問題だなぁと思ったのですが
32
+
33
+ 前に私が作ったアニメーションプログラムで一度作成してから中身を差し替えるという方法でこのエラー「async handler deleted by the wrong thread」が一回も出なかったので、あらかじめウィジェットを作成しておき中身を差し替えるという手段がありかもしれません。
34
+
35
+ (こちらはフルのコードを載せます。)
36
+
37
+ ```x
38
+
39
+
40
+
41
+ import time
42
+
43
+ import tkinter as tk
44
+
45
+ from PIL import Image, ImageTk
46
+
47
+ import threading
48
+
49
+
50
+
51
+
52
+
53
+ root = tk.Tk()
54
+
55
+ root.geometry("800x600")
56
+
57
+ canvas = tk.Canvas(root, width=190, # 幅を設定
58
+
59
+ height=200,
60
+
61
+ )
62
+
63
+
64
+
65
+ canvas.place(x=0,y=0)
66
+
67
+ image = Image.open("1.jpg")
68
+
69
+ image.thumbnail((200, 200), Image.ANTIALIAS)
70
+
71
+ img = ImageTk.PhotoImage(image) # 表示するイメージを用意
72
+
73
+
74
+
75
+
76
+
77
+ id = canvas.create_image( # キャンバス上にイメージを配置
78
+
79
+ 0, # x座標
80
+
81
+ 0, # y座標
82
+
83
+ image = img, # 配置するイメージオブジェクトを指定
84
+
85
+ anchor=tk.NW # 配置の起点となる位置を左上隅に指定
86
+
87
+ )
88
+
89
+
90
+
91
+ image = Image.open("2.jpg")
92
+
93
+ image.thumbnail((200, 200), Image.ANTIALIAS)
94
+
95
+ img1 = ImageTk.PhotoImage(image) #
96
+
97
+
98
+
99
+ image = Image.open("3.jpg")
100
+
101
+ image.thumbnail((200, 200), Image.ANTIALIAS)
102
+
103
+ img2 = ImageTk.PhotoImage(image) #
104
+
105
+
106
+
107
+ image = Image.open("4.jpg")
108
+
109
+ image.thumbnail((200, 200), Image.ANTIALIAS)
110
+
111
+ img3 = ImageTk.PhotoImage(image) #
112
+
113
+
114
+
115
+ def animation(sleeptime) :
116
+
117
+ while 1 :
118
+
119
+ canvas.itemconfig(id,image=img)
120
+
121
+ time.sleep(sleeptime)
122
+
123
+ canvas.itemconfig(id,image=img1)
124
+
125
+ time.sleep(sleeptime)
126
+
127
+ canvas.itemconfig(id,image=img2)
128
+
129
+ time.sleep(sleeptime)
130
+
131
+ canvas.itemconfig(id,image=img3)
132
+
133
+ time.sleep(sleeptime)
134
+
135
+
136
+
137
+
138
+
139
+ th1 = threading.Thread(target=animation,args=(1,))
140
+
141
+ th1.start()
142
+
143
+
144
+
145
+ tk.mainloop()
146
+
147
+
148
+
149
+
150
+
151
+ ```
152
+
153
+ 回答してくれた方がおっしゃったように、tkinterはウィジェットをクラス化して書いたほうがいいですね。ただ、最初に提示しようとしたコードは探り探り書いていてもう400行くらいになってしまったのでクラス化する体力がないです
154
+
155
+
156
+
157
+ で、解決策の続きですが、根本的な解決策はいまだに私は分かりません。さっきのstackoverflowのしつもんをみてもジェットを作成している部分だけをクラス化してメインスレッドで走らせているようにしているので、もうどうやってもサブスレッドではウィジェットを作成できないのかもしれません。非常に残念です・・・
158
+
159
+
160
+
161
+
162
+
163
+ ```ここに言語を入力
164
+
165
+ //ここはスレッドを逐一作る処理を書き忘れていました、ソースを全部乗せるのはすいません、ちょっと無理です・・・・
166
+
167
+ def thread_button():
168
+
169
+ th1 = threading.Thread(target=btn_click1)
170
+
171
+ th1.start()
172
+
173
+ ```
174
+
175
+
176
+
177
+ ---
178
+
1
179
  前にも質問させていただきましたが、[こちらの質問](https://teratail.com/questions/149204)ですが
2
180
 
3
181
  **async handler deleted by the wrong thread**というエラーを検索しても日本語の情報が全くありません。
@@ -12,6 +190,8 @@
12
190
 
13
191
 
14
192
 
193
+
194
+
15
195
  ```ここに言語を入力
16
196
 
17
197
  import tkinter as tk