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

PyQt5 SplashScreen加载完成后主窗口无法显示直接退出问题

问题根因

进度走完程序直接退出的核心原因是变量作用域+Python垃圾回收机制:你在loading方法内部创建的MainWindow和ui都是方法级别的局部变量,当loading方法执行结束后,这两个局部变量没有任何外部引用,会被Python自动回收,对应的窗口对象刚执行完show()就被销毁,程序自然直接退出,和主窗口本身的代码逻辑无关。

修复方案

方案1:快速修复(改动最小)

把主窗口、UI实例绑定为SplashScreen类的实例属性,让对象生命周期和SplashScreen实例绑定,避免被垃圾回收。
修正后的loading方法代码如下:

def loading(self):
    # 设置进度条值
    self.progressBar.setValue(self.counter)
    # 进度走完后跳转主窗口
    if self.counter >= self.n:
        self.timer.stop()
        self.close()
        # 注意:不要用局部变量,绑定为self的属性
        self.main_window = QtWidgets.QMainWindow()
        self.window_app = WindowApp()
        self.window_app.setupUi(self.main_window)
        self.main_window.show()

    self.counter += 1

方案2:规范实现(低耦合)

不建议在启动屏类内部直接耦合主窗口创建逻辑,可以给SplashScreen添加加载完成的自定义信号,在程序入口层监听信号创建主窗口,代码结构更清晰:

  • 第一步:给SplashScreen类添加自定义信号
from PyQt5.QtCore import pyqtSignal

class SplashScreen(QWidget):
    # 定义加载完成信号
    load_finished = pyqtSignal()
    # 其余__init__、initUI代码保持原有逻辑不变
  • 第二步:修改loading方法,进度走完时发射信号,不在类内部创建主窗口
def loading(self):
    self.progressBar.setValue(self.counter)
    if self.counter >= self.n:
        self.timer.stop()
        self.close()
        # 发射加载完成信号
        self.load_finished.emit()
    self.counter += 1
  • 第三步:修改程序入口代码,监听信号后创建主窗口
def show_main_window():
    global main_window, ui
    main_window = QtWidgets.QMainWindow()
    ui = WindowApp()
    ui.setupUi(main_window)
    main_window.show()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    splash = SplashScreen()
    splash.show()
    # 监听加载完成信号,触发主窗口显示
    splash.load_finished.connect(show_main_window)
    sys.exit(app.exec_())

注意:这里主窗口实例也要避免放在函数内部作为局部变量,要么声明为global全局变量,要么把主程序逻辑封装成类绑定为实例属性,否则同样会被垃圾回收导致窗口闪退。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 08:51:34