質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

3回答

3556閲覧

python 非同期 エラー 「async handler deleted by the wrong thread」について

flan

総合スコア146

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2018/10/02 08:37

編集2018/10/03 11:41

追記

ご指摘ありがとうございます。
修正後のコードと、原因が何となく分かったので追記します。
参考にしたstackoverflow
で挙げられいていた質問を読み返したらこのようなことが書いてありました。

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
(tkinterのウィジェットはメインスレッド以外で作成してはならない)

もし作成した場合

When you exit the process the cleanup is being done from the process primary thread
(そのプロセスを削除する)

みたいです。つまりメインスレッドtk()からtk.loop()以外でウィジェットを作成してはならないということでしょうかね・・
これは非常に困った問題だなぁと思ったのですが
前に私が作ったアニメーションプログラムで一度作成してから中身を差し替えるという方法でこのエラー「async handler deleted by the wrong thread」が一回も出なかったので、あらかじめウィジェットを作成しておき中身を差し替えるという手段がありかもしれません。
(こちらはフルのコードを載せます。)

import time import tkinter as tk from PIL import Image, ImageTk import threading root = tk.Tk() root.geometry("800x600") canvas = tk.Canvas(root, width=190, # 幅を設定 height=200, ) canvas.place(x=0,y=0) image = Image.open("1.jpg") image.thumbnail((200, 200), Image.ANTIALIAS) img = ImageTk.PhotoImage(image) # 表示するイメージを用意 id = canvas.create_image( # キャンバス上にイメージを配置 0, # x座標 0, # y座標 image = img, # 配置するイメージオブジェクトを指定 anchor=tk.NW # 配置の起点となる位置を左上隅に指定 ) image = Image.open("2.jpg") image.thumbnail((200, 200), Image.ANTIALIAS) img1 = ImageTk.PhotoImage(image) # image = Image.open("3.jpg") image.thumbnail((200, 200), Image.ANTIALIAS) img2 = ImageTk.PhotoImage(image) # image = Image.open("4.jpg") image.thumbnail((200, 200), Image.ANTIALIAS) img3 = ImageTk.PhotoImage(image) # def animation(sleeptime) : while 1 : canvas.itemconfig(id,image=img) time.sleep(sleeptime) canvas.itemconfig(id,image=img1) time.sleep(sleeptime) canvas.itemconfig(id,image=img2) time.sleep(sleeptime) canvas.itemconfig(id,image=img3) time.sleep(sleeptime) th1 = threading.Thread(target=animation,args=(1,)) th1.start() tk.mainloop()

回答してくれた方がおっしゃったように、tkinterはウィジェットをクラス化して書いたほうがいいですね。ただ、最初に提示しようとしたコードは探り探り書いていてもう400行くらいになってしまったのでクラス化する体力がないです

で、解決策の続きですが、根本的な解決策はいまだに私は分かりません。さっきのstackoverflowのしつもんをみてもジェットを作成している部分だけをクラス化してメインスレッドで走らせているようにしているので、もうどうやってもサブスレッドではウィジェットを作成できないのかもしれません。非常に残念です・・・

//ここはスレッドを逐一作る処理を書き忘れていました、ソースを全部乗せるのはすいません、ちょっと無理です・・・・ def thread_button(): th1 = threading.Thread(target=btn_click1) th1.start()

前にも質問させていただきましたが、こちらの質問ですが
async handler deleted by the wrong threadというエラーを検索しても日本語の情報が全くありません。
stackoverfloweで似たような質問がありましたが、いまいち理解できませんでした。

わたしのソースコードは以下の通りです、スレッド関連はいろいろ調べましたが、お手上げ状態です。tkinterと関連しているためおこると考察しているのですが・・・
お力を借りたいです。

import tkinter as tk import thread def thread_button(): th1.start() def btn_click(): res = requests.get("http://aaa.com") root = tk.Tk() th1 = threading.Thread(target=btn_click) button= tk.Button(frame1_1,text="TEST", command=thread_button) button.pack() root.mainloop()

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

自己解決

解決方法を追記に記載しました。

投稿2018/10/05 15:08

flan

総合スコア146

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

問題が再現するコードを提示してください。
以下のコードでは再現しませんでした。

python

1import tkinter as tk 2import threading 3 4def thread_button(): 5 th1.start() 6 7def btn_click(): 8 print("btn_click()") 9 import time 10 time.sleep(1) 11 print("start requests") 12 import requests 13 res = requests.get("https://teratail.com/") 14 print(res) 15 print("end thread") 16 17main = tk.Tk() 18th1 = threading.Thread(target=btn_click) 19button = tk.Button( text="Test", command=thread_button) 20button.pack() 21 22main.mainloop()

bash

1$ python t.py 2btn_click() 3start requests 4<Response [200]> 5end thread

ただ、このコードだと、ボタンクリック2回目以降うまく動作しないので、使い物になりませんが。

投稿2018/10/02 09:45

t_obara

総合スコア5488

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

stackoverfloweで似たような質問がありましたが、いまいち理解できませんでした。

Tcl_AsyncDelete Error Multithreading Python

上記リンクの回答に動くコード書いてくれてますよ?
コピペするだけで動いています。
それを雛形にボタンなり追加して動かして練習した方が近道かと。

あとtkinter使う場合はクラスを作ってインスタンス化したほうがいいです。
特にスレッド使いたいなら尚更かと。

投稿2018/10/02 09:04

opyon

総合スコア1009

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問