【发布时间】:2021-03-08 12:09:48
【问题描述】:
我有一个项目,其中被动 GUI 在其自己的线程中运行并由主线程操作。特别是主线程使用event_generate关闭窗口:
from tkinter import Tk
import threading
import time
import queue
q = queue.Queue()
class Window:
def __init__(self):
self.root = Tk()
self.root.title("test")
self.root.bind("<<custom_close_event>>", self.close)
def close(self, event):
print("quit")
self.root.destroy()
def create_window():
window = Window()
q.put(window)
window.root.mainloop()
print("###########")
# Window creation executed in different thread
t1 = threading.Thread(target=create_window)
t1.start()
window = q.get()
time.sleep(2)
window.root.event_generate("<<custom_close_event>>")
print("end")
程序崩溃,输出如下:
quit
###########
Tcl_AsyncDelete: async handler deleted by the wrong thread
[1] 21572 IOT instruction (core dumped) python window_test.py
根据this discussion,看来是多线程环境下对象清理的顺序有问题。使对象无效(在我的情况下为 window)和调用 gc.collect 的建议并没有解决问题。
我该怎么办?
【问题讨论】:
-
你不应该从不同的线程访问 tkinter 对象。
-
event_generate可以根据documentation(线程或进程部分)从另一个线程安全地调用。 -
是的,但是对某些对象的引用仍然存在,这就是 tcl 崩溃的原因
标签: python multithreading tkinter