Search code examples
pythonpyqtpyqt5splash-screenqsplashscreen

How to change the image inside a Splash Screen


I am developing an app that when started needs to check various things like if the modules are found, if a connection to a microcontroller is working, etc. So I decided to make a splash screen where each of these steps show a message. What I thought was to make several images that have the text saying ('Loading modules...'), ('Checking connection...') and change them everytime the step is being run. The following code is what I thought of:

images = ["path1", "path2", ...]
app = QApplication(sys.argv)

for i in images:
   pixmap = QPixmap(i)
   splash = QSplashScreen(pixmap)

   splash.show()
   QTimer.singleShot(3000, splash.close) #the timer is just to pretend some process is running
   app.processEvents()
   app.exec_()

This code only shows the last of the images, not each separated by 3 seconds. Any clue on how I can fix this?


Solution

  • You must create signals that indicate the states and change the images:

    import sys
    
    from PyQt5 import QtCore, QtGui, QtWidgets
    
    
    class Manager(QtCore.QObject):
        """Class that simulates the loading steps"""
    
        started = QtCore.pyqtSignal()
        loaded_modules = QtCore.pyqtSignal()
        connected = QtCore.pyqtSignal()
        finished = QtCore.pyqtSignal()
    
        def __init__(self, parent=None):
            super().__init__(parent)
    
        def start(self):
            self.started.emit()
            for i, step in enumerate((self.loaded_modules, self.connect, self.finish), 1):
                QtCore.QTimer.singleShot(i * 2000, step)
    
        def load_modules(self):
            self.loaded_modules.emit()
    
        def connect(self):
            self.connected.emit()
    
        def finish(self):
            self.finished.emit()
    
    
    class SplashScreen(QtWidgets.QSplashScreen):
        @QtCore.pyqtSlot()
        def handle_started(self):
            self.show()
            self.setPixmap(QtGui.QPixmap("started.png"))
    
        @QtCore.pyqtSlot()
        def handle_loaded_modules(self):
            self.setPixmap(QtGui.QPixmap("loaded_modules.png"))
    
        @QtCore.pyqtSlot()
        def handle_connected(self):
            self.setPixmap(QtGui.QPixmap("connected.png"))
    
        @QtCore.pyqtSlot()
        def handle_finished(self):
            self.close()
    
    
    def main():
        app = QtWidgets.QApplication(sys.argv)
    
        w = QtWidgets.QMainWindow()
        w.resize(640, 480)
    
        manager = Manager()
        splash_screen = SplashScreen()
    
        manager.started.connect(splash_screen.handle_started)
        manager.loaded_modules.connect(splash_screen.handle_loaded_modules)
        manager.connected.connect(splash_screen.handle_connected)
        manager.finished.connect(splash_screen.handle_finished)
        manager.finished.connect(w.show)
    
        manager.start()
    
        app.exec_()
    
    
    if __name__ == "__main__":
        main()