简体   繁体   中英

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

I am trying to create a loading screen because my MainWindow takes over 10 seconds to open, which is ok as long as I have a loading screen.

Here I have some code and when i run it, it will open a loading screen.

After the loading screen pops up i want it to immediately try to open the MainWindow. (On my actual app this would take 10 seconds to open) I have used time.sleep to simulate the time my actual programme would take to open as this is just smaller code for you to read. However my real code will not include any sleep it will just naturally take 10 seconds to load.

How can I make it so once my loading screen is visible it will immediately open MainWindow? Currently I have not asked it to do anything, the loading screen just opens and that's it.

What extra code do I need to make it open MainWindow? Ideally I would like to update the progress bar as this happens but that is not nessecary for now I just want to know how to open MainWindow immediately from the loading screen, thanks.

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_())

You should not modify the code generated by pyuic so you must recreate those files that for my solution will be splash_ui.py and main_ui.py.

The idea is that the time consuming task should not run in the main thread but in a secondary thread and emit signals when it starts and ends that show and hide the splashscreen.

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_())

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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