簡體   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