使用 PyQt5 启动画面覆盖模块加载时间

Using PyQt5 splash screen to cover module load time

我创建了一个 GUI 来加载依赖于大量模块的库 my_lib。它将使用 PyInstaller 转换为可执行文件。

我想创建启动画面来隐藏较长(超过 5 秒)的加载时间。

一种方法是使用 PyInstaller 的 --splash 参数,但这将独立于程序并使用计时器工作。

另一种方法是。这是主要脚本的示例:

# various imports including standard library and PyQt.
from my_lib import foo, bar, docs_url, repo_url


class MainWindow(QMainWindow):

    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)
        self.action_docs.triggered.connect(lambda x: QDesktopServices.openUrl(QUrl(docs_url)))
        self.action_code.triggered.connect(lambda x: QDesktopServices.openUrl(QUrl(repo_url)))

    def show_splash(self):
        self.splash = QSplashScreen(QPixmap("path\to\splash.png"))
        self.splash.show()
        # Simple timer to be replaced with better logic.
        QTimer.singleShot(2000, self.splash.close)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    app.setStyle(QStyleFactory.create('fusion'))
    main = MainWindow()
    main.show()
    main.show_splash()
    sys.exit(app.exec_())

上面代码的问题在于导入是在顶部完成的然后启动画面被打开,这就违背了这一点。 此外,MainWindow class 的定义取决于从 my_lib.

导入的对象

当GUI的基本定义依赖它们时,如何隐藏重型模块的加载时间? 我有什么遗漏吗?有可能吗?

编辑:这种做法是不必要的。正如@musicamante 在评论中指出的那样,上面的(编辑过的)示例没有引发任何错误,可以毫无问题地使用。


在考虑了@musicamante 的评论后,我有了将 __ main __ 条件中的逻辑分成两部分的想法。一个在大量进口之前,另一个在最后。所以它是这样的:

if __name__ == '__main__':
    app = QApplication(sys.argv)
    app.setStyle(QStyleFactory.create('fusion'))
    splash_object = QSplashScreen(QPixmap("path\to\splash.png"))
    splash_object.show()

#
# Load the heavy libraries, including my_lib.
#

class MainWindow(QMainWindow):

    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)

if __name__ == '__main__':
    splash_object.close()
    main = MainWindow()
    main.show()
    sys.exit(app.exec_())

这似乎工作得很好,但我不确定这种拆分是否有任何副作用。

应该注意的是,大部分启动时间似乎来自可执行文件的解包。

编辑:This answer 建议采用类似的方法。