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

Python QApplication启动子线程后无法正常关闭问题

问题解决:Qt应用关闭时因后台线程阻塞无法终止

问题根源

后台线程中调用的sched.scheduler.run()是阻塞式方法,会一直等待调度的备份任务执行完毕才结束线程。而Python默认线程为非守护线程,主线程(Qt应用)退出时会等待所有非守护线程完成,导致应用冻结无法正常终止。

解决方案1:将线程设为守护线程

直接把后台线程标记为守护线程,主线程退出时会自动终止该线程,实现快速关闭:

if __name__ == '__main__':
    # 设置daemon=True将线程转为守护线程
    x = threading.Thread(target=backupGiornaliero, daemon=True)
    x.start()

    app = QApplication(sys.argv)
    vistaLogin = LoginView(app)
    vistaLogin.show()
    sys.exit(app.exec())

解决方案2:优雅终止调度器(推荐)

如果需要避免强制中断备份任务,可监听Qt应用的aboutToQuit信号,在关闭时主动终止调度器的阻塞状态:

首先修改backupGiornaliero函数,添加终止标记并循环检查调度状态:

import threading

# 线程终止标记
stop_scheduler = threading.Event()

def backupGiornaliero():
    global stop_scheduler
    dataOggi=datetime.today().strftime('%Y-%m-%d')
    orarioBackup = " 22:00:00"
    dataOrarioBackup = str(dataOggi+orarioBackup)
    datatimeBackup = datetime.strptime(dataOrarioBackup, '%Y-%m-%d %H:%M:%S')

    if datetime.now() < datatimeBackup:
        unixDataBackup = time.mktime(datatimeBackup.timetuple())
    else:
        unixDataBackup = time.mktime(datatimeBackup.timetuple())+ float(86400)

    print("unix timestamp dell'orario di backup di oggi "+str(unixDataBackup))

    s = sched.scheduler(time.time, time.sleep)
    s.enterabs(unixDataBackup, 0, BackupModel().eseguiBackup)
    
    # 循环执行调度,同时检查终止信号
    while not stop_scheduler.is_set():
        # 非阻塞执行调度事件,超时1秒避免永久阻塞
        remaining = s.run(blocking=False)
        if remaining is None:
            break
        time.sleep(1)

    print("备份线程已正常终止")

然后在主函数中绑定应用退出信号:

if __name__ == '__main__':
    x = threading.Thread(target=backupGiornaliero)
    x.start()

    app = QApplication(sys.argv)
    
    # 应用退出时触发线程终止
    def on_app_quit():
        global stop_scheduler
        stop_scheduler.set()
        x.join()  # 等待线程正常退出
    
    app.aboutToQuit.connect(on_app_quit)

    vistaLogin = LoginView(app)
    vistaLogin.show()
    sys.exit(app.exec())

方案对比

  • 方案1实现简单,但可能中断正在执行的备份任务;
  • 方案2更优雅,确保线程正常退出,避免备份任务被强制中断。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 21:15:12