繁体   English   中英

如何从 Pyqt5 中没有按钮的 SplashScreen 打开 MainWindow?

[英]How to open MainWindow from a SplashScreen without button in Pyqt5?

我正在尝试创建一个加载屏幕,因为我的 MainWindow 需要 10 多秒才能打开,只要我有一个加载屏幕就可以了。

这里我有一些代码,当我运行它时,它会打开一个加载屏幕。

加载屏幕弹出后,我希望它立即尝试打开 MainWindow。 (在我的实际应用程序上,这需要 10 秒才能打开)我使用 time.sleep 来模拟我的实际程序打开所需的时间,因为这只是供您阅读的较小代码。 但是,我的真实代码不会包含任何睡眠,它自然需要 10 秒才能加载。

我怎样才能做到这一点,一旦我的加载屏幕可见,它将立即打开 MainWindow? 目前我还没有要求它做任何事情,加载屏幕刚刚打开,就是这样。

我需要什么额外的代码才能打开 MainWindow? 理想情况下,我想在发生这种情况时更新进度条,但现在这不是必需的,我只想知道如何从加载屏幕立即打开 MainWindow,谢谢。

from PyQt5 import QtCore, QtGui, QtWidgets
import time   

class Ui_SplashScreen(object):    
    def setupUi(self, SplashScreen):
        SplashScreen.setObjectName("SplashScreen")
        SplashScreen.resize(800, 600)
        self.centralwidget = QtWidgets.QWidget(SplashScreen)
        self.centralwidget.setObjectName("centralwidget")
        self.progressBar = QtWidgets.QProgressBar(self.centralwidget)
        self.progressBar.setGeometry(QtCore.QRect(190, 220, 461, 91))
        self.progressBar.setProperty("value", 24)
        self.progressBar.setObjectName("progressBar")
        SplashScreen.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(SplashScreen)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
        self.menubar.setObjectName("menubar")
        SplashScreen.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(SplashScreen)
        self.statusbar.setObjectName("statusbar")
        SplashScreen.setStatusBar(self.statusbar)   
        self.retranslateUi(SplashScreen)
        QtCore.QMetaObject.connectSlotsByName(SplashScreen)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        time.sleep(10)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(310, 180, 341, 161))
        font = QtGui.QFont()
        font.setPointSize(40)
        self.label.setFont(font)
        self.label.setObjectName("label")
        MainWindow.setCentralWidget(self.centralwidget)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.label.setText(_translate("MainWindow", "MY APP"))

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    SplashScreen = QtWidgets.QMainWindow()
    ui = Ui_SplashScreen()
    ui.setupUi(SplashScreen)
    SplashScreen.show()
    sys.exit(app.exec_())

您不应该修改 pyuic 生成的代码,因此您必须重新创建对于我的解决方案将是 splash_ui.py 和 main_ui.py 的文件。

这个想法是,耗时的任务不应该在主线程中运行,而是在辅助线程中运行,并在启动和结束时发出信号,显示和隐藏启动画面。

import threading
import sys

from PyQt5.QtCore import QObject, pyqtSignal
from PyQt5.QtWidgets import QApplication, QMainWindow

from main_ui import Ui_MainWindow
from splash_ui import Ui_SplashScreen

def long_running_function():
    import time

    time.sleep(10)

class Worker(QObject):
    started = pyqtSignal()
    finished = pyqtSignal()

    def start(self):
        threading.Thread(target=self._execute, daemon=True).start()

    def _execute(self):
        self.started.emit()
        # FIXME
        long_running_function()
        self.finished.emit()


class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)


class SplashScreen(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.ui = Ui_SplashScreen()
        self.ui.setupUi(self)

def main():
    app = QApplication(sys.argv)

    splash_screen = SplashScreen()
    main_window = MainWindow()

    worker = Worker()
    worker.started.connect(splash_screen.show)
    worker.finished.connect(splash_screen.close)    
    worker.finished.connect(main_window.show)
    worker.start()

    sys.exit(app.exec_())

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM