在子线程执行time.sleep()仍致Tkinter程序冻结的技术求助
问题分析与解决办法
嘿,我一眼就揪出你代码里的问题啦!
核心错误原因
你创建线程的这行代码犯了个典型的小错误:
t = threading.Thread(target=self.removeError())
这里的self.removeError()是直接执行了这个函数,而不是把函数本身作为线程的目标任务。这就导致主线程会先跑去执行removeError里的time.sleep(5),整个程序自然就被卡住了,直到5秒sleep结束,才会继续执行后面的print和线程启动——完全违背了你用线程实现异步的初衷!
修复方案1:正确使用线程
把target参数改成函数对象(去掉括号),这样线程启动后才会去调用这个函数:
# 修正后的线程创建代码 t = threading.Thread(target=self.removeError) t.start()
改完之后,createError里的代码会立刻执行,print("Function called")会马上输出,而removeError会在新线程里等待5秒后执行,程序也就不会冻结了。
更推荐的方案2:用Tkinter自带的after方法
因为Tkinter的GUI操作并不是线程安全的,虽然简单的itemconfig可能暂时没问题,但复杂场景下容易出现奇怪的bug。Tkinter本身提供了after方法来处理延迟任务,完全不需要额外线程:
def createError(self, text): background.itemconfig(errorText, text=text, state=NORMAL, font="Neoteric 11 bold") background.itemconfig(errorBG, state=NORMAL) # 用after替代线程,5000毫秒(5秒)后调用removeError background.after(5000, self.removeError) print("Function called") # 现在会立刻打印啦
这种方式是Tkinter官方推荐的异步延迟处理方式,既安全又简洁,完全不会导致程序冻结。
内容的提问来源于stack exchange,提问作者James
相关产品推荐
相关产品推荐

