简体   繁体   English

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

[英]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.我正在尝试创建一个加载屏幕,因为我的 MainWindow 需要 10 多秒才能打开,只要我有一个加载屏幕就可以了。

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.加载屏幕弹出后,我希望它立即尝试打开 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. (在我的实际应用程序上,这需要 10 秒才能打开)我使用 time.sleep 来模拟我的实际程序打开所需的时间,因为这只是供您阅读的较小代码。 However my real code will not include any sleep it will just naturally take 10 seconds to load.但是,我的真实代码不会包含任何睡眠,它自然需要 10 秒才能加载。

How can I make it so once my loading screen is visible it will immediately open MainWindow?我怎样才能做到这一点,一旦我的加载屏幕可见,它将立即打开 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?我需要什么额外的代码才能打开 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.理想情况下,我想在发生这种情况时更新进度条,但现在这不是必需的,我只想知道如何从加载屏幕立即打开 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_())

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.您不应该修改 pyuic 生成的代码,因此您必须重新创建对于我的解决方案将是 splash_ui.py 和 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_())

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

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