Search code examples
c++qtqmlqpixmapqsplashscreen

Qt : Display a picture during application loading


I want add a splash screen to an application which is slow to load. I have create a simple app to test.

main.cpp :

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QPixmap pixmap("/home/helene/Images/my_image.png");
    if (pixmap.isNull())
    {
        pixmap = QPixmap(300, 300);
        pixmap.fill(Qt::magenta);
    }

    QSplashScreen *splash = new QSplashScreen(pixmap);
    splash->show();
    splash->showMessage("Loaded modules dsjhj");

    QQmlApplicationEngine engine;
    engine.load(QUrl("qrc:/main.qml"));

    QObject *topLevel = engine.rootObjects().value(0);
    QQuickWindow *window = qobject_cast<QQuickWindow *>(topLevel);
    if ( !window )
    {
        qWarning("Error: Your root item has to be a Window.");
        return -1;
    }
    else
    {
        window->showFullScreen();
    }
    return app.exec();
}

main.qml

Window {
    visible: false
    width: 360
    height: 360

    property variant t: determineT()
    MouseArea {
        anchors.fill: parent
        onClicked: {
            Qt.quit();
        }
    }

    Text {
        text: qsTr("Hello World")
        anchors.centerIn: parent
    }

    function determineT() {
        for(var i=0; i<1000000000; i++);
    }
}

I have added a long function to rise the time of loading. When the app state, I can see "the shadow" of the picture. The picture seems completely loading just before the application. I have tried with image on resources and with absolute path but the problem is the same. Picture of the "shadow"


Solution

  • Typically QSplashScreen is used before the main windows is shown during which you want to do some initialization tasks. Since the splash screen is displayed before the event loop has started, you should periodically call QApplication::processEvents() to process events related to splash screen :

    QSplashScreen splash(pixmap);
    splash.show();
    qApp->processEvents(QEventLoop::AllEvents);
    
    //Initialization
    ...
    
    qApp->processEvents(QEventLoop::AllEvents);
    
    //Initialization
    ...
    

    In your case you are showing the splash screen and immediately load the qml file which enters a long loop, hence the splash screen events does not get processed. Try this after showing the splash screen and before loading the qml file :

    qApp->processEvents(QEventLoop::AllEvents);