You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现带可终止线程的CustomTkinter进度条?

修正后的可终止线程+CTk进度条实现

你的代码存在几个关键问题导致功能失效,以下是修复后的完整实现,可实现进度条运行5秒后被中断的效果:

import customtkinter as ctk
import threading
import time

class StoppableThread(threading.Thread):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._stop_event = threading.Event()

    def stop(self):
        self._stop_event.set()

    def stopped(self):
        return self._stop_event.is_set()

class App(ctk.CTk):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.geometry("200x100")

        # 创建进度条
        self.progress_bar = ctk.CTkProgressBar(master=self, height=15, width=150, mode='determinate')
        self.progress_bar.place(x=10, y=10)
        self.progress_bar.set(0)

        # 启动线程
        self.alg_thread = Algorithm(self)
        self.alg_thread.start()

        # 5秒后触发停止操作(非阻塞)
        self.after(5000, self.stop_thread)

    def stop_thread(self):
        self.alg_thread.stop()
        print("线程已终止")

class Algorithm(StoppableThread):
    def __init__(self, app, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.app = app  # 保存App实例,用于安全更新UI

    def run(self):
        n = 100  # 增加迭代次数,让进度条动画更明显
        iter_step = 1 / n
        progress = 0

        while not self.stopped():
            if progress >= 1:
                progress = 0  # 进度满了重置,方便演示

            # 主线程安全更新进度条
            self.app.after(0, lambda p=progress: self.app.progress_bar.set(p))
            
            progress += iter_step
            time.sleep(0.05)  # 模拟任务耗时

        # 线程终止后重置进度条
        self.app.after(0, lambda: self.app.progress_bar.set(0))

if __name__ == "__main__":
    app = App()
    app.mainloop()

关键改动说明:

  • 线程执行逻辑:Algorithm类重写了run()方法,线程启动后自动执行任务循环,替代原代码中未被调用的test()方法
  • UI线程安全:所有进度条更新操作通过app.after(0, ...)提交到主线程执行,避免子线程直接操作UI组件导致的线程安全问题
  • 非阻塞延迟:用self.after(5000, ...)替代time.sleep(5),不会阻塞主线程,保证UI始终响应
  • 实例引用传递:将App实例传入Algorithm线程,让线程能安全访问并更新UI组件
  • 停止信号检查:在任务循环中持续检查stopped()状态,收到停止信号后立即终止循环,并重置进度条

内容的提问来源于stack exchange,提问作者Andrew Eaves

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 07:57:34