调用函数时线程未启动?Tkinter定时线程问题求助
Tkinter线程未启动问题排查与解决
问题描述
我正在开发一个通过Tkinter制作的仪表盘程序,需定期检查多项内容并返回数据。为简化线程启停操作,自定义了继承threading.Thread的Timer类:
import threading import time import tkinter as tk class Timer(threading.Thread): def __init__(self): self._timer_runs = threading.Event() self._timer_runs.set() super().__init__() def start(self): while self._timer_runs.is_set(): self.timed_func() time.sleep(self.__class__.interval) def stop(self): self._timer_runs.clear()
随后创建继承Timer的子类GetDataFromPlaces,实现timed_func方法:
class GetDataFromPlaces(Timer): interval = 3600 #seconds def timed_func(self): # The code to get data from said places, tested and working correctly pass
我需要该函数在仪表盘启动时运行,于是在Application初始化中启动线程:
class Application(tk.Tk): def __init__(self): super().__init__() self.timed_func = GetDataFromPlaces() self.timed_func.start()
但Tkinter窗口打开后线程未启动,请问原因是什么?
编辑说明:这是我的第一个大型项目,我还是新手,若术语使用不当或信息有问题,提前致歉。
问题原因与解决方法
核心问题是你重写了threading.Thread的start方法,但完全没有调用父类的start()——这才是启动新线程的关键操作。
threading.Thread.start()的作用是创建并启动一个独立的操作系统线程,让这个新线程去执行run()方法中的逻辑。而你现在的start方法是直接在Tkinter主线程里执行了死循环,这会直接卡住主线程,导致Tkinter窗口无法正常渲染,自然也不存在“启动新线程”的效果。
正确的修改方式是把定时循环逻辑放到run()方法中,保留父类的start()方法:
class Timer(threading.Thread): def __init__(self): self._timer_runs = threading.Event() self._timer_runs.set() super().__init__() def run(self): # 重写run方法而非start while self._timer_runs.is_set(): self.timed_func() time.sleep(self.__class__.interval) def stop(self): self._timer_runs.clear()
修改后,当你调用self.timed_func.start()时,会自动启动一个新线程,在新线程里执行run()中的定时循环,既不会阻塞Tkinter主线程,线程也能正常执行定时任务。
额外补充两个注意点:
- 确保代码中导入了
time模块,否则time.sleep会抛出异常 GetDataFromPlaces的timed_func方法要保证缩进正确,否则代码无法正常执行
内容的提问来源于stack exchange,提问作者Balouuzard
相关产品推荐
相关产品推荐

