QML: Show animated splash screen at startup


QML is a great way to make nice interfaces but, currently, suffer a bit in the initial phase of loading since it could take some time if your QML code is complex or there are many image resources to load. In this case show a splash screen can be a good way to "inform" the user the app is started. More better have an animation will inform also the app is alive and still loading.


Full project can be found on GitHub here.

Show a splash screen is a quite easy task but keep the animation running require some trick since the initial QML loading take a lot of resources that, in normal case, stop for a bit the main GUI loop (and then the animation too). Basically the main qml file to load have to be divided in the parts, one is the loading of the simple window show the splash screen that, once done, will start a secondary loader set in asynchronous mode for load the main qml app code in a background thread. Follow the code of main.qml:

import QtQml 2.2
import QtQuick 2.6

Item {
    Loader {
        id: mainWindowLoader
        active: false
        source: "qrc:/window.qml"
        asynchronous: true
        onLoaded: {
            item.visible = true;
            splashScreenLoader.item.visible = false;
            splashScreenLoader.source = "";
        }
    }

    Loader {
        id: splashScreenLoader
        source: "qrc:/splashscreen.qml"
        onLoaded: {
            mainWindowLoader.active = true;
        }
    }
}

As you can see there are two Loaders but the first is not active. At program startup the second loader is started. Once finished loading the window splash screen it start the first loader who load the main window (non visible). The splash screen window is quite simple, a text message and BusyIndicator control showing the animation for give the "feel" the app is alive and loading. Please note than once main window has been loaded it is showed and the splash screen window is unloaded by setting an empty string to loader source.

import QtQuick 2.0
import QtQuick.Controls 2.0
import QtQuick.Window 2.2

Window {
    id: splashScreen
    modality: Qt.ApplicationModal
    flags: Qt.SplashScreen
    width: 300
    height: 300

    Rectangle {
 id: splashRect
 anchors.fill: parent
 color: "white"
        border.width: 1
 border.color: "black"
  
 Text {
     id: initializationErrorMessage
     text: "This is the splash screen"
     anchors.horizontalCenter: parent.horizontalCenter
     anchors.top: parent.top
            anchors.topMargin: 50
     font.bold: true
     font.pixelSize: 20
     color: "black"
 }

 BusyIndicator {
     id: busyAnimation
     anchors.horizontalCenter: parent.horizontalCenter
     anchors.bottom: parent.bottom
     anchors.bottomMargin: parent.height / 5
     width: parent.width / 2
     height: width
     running: true
 }
    }

    Component.onCompleted: visible = true
}

Here the code of main window. Please note the red part is only a bad trick to make a short delay before window is ready just for simulate an heavy loading:

import QtQml 2.2
import QtQuick 2.6
import QtQuick.Window 2.2
import QtQuick.Controls 2.0

ApplicationWindow {
    id: mainWindow
    flags: Qt.Window | Qt.WindowTitleHint | Qt.WindowSystemMenuHint | Qt.WindowCloseButtonHint
    width: 300
    height: 400
    visible: false
    title: "Scresh Screen Test"

    Component.onCompleted: {
        var timeout = new Date().valueOf() + 3000;
        while(timeout > new Date().valueOf()) {}
    }

    Text {
        text: "Window ready!"
        anchors.centerIn: parent
        font.bold: true
        font.pixelSize: 20
        color: "black"
    }
}

Please note since the main window is loaded in a background thread the loading priority is lower than main thread. This mean the loading will take more time compared to directly load the main window from main thread. Currently is the best solution I found to have an animated splash screen without animation lags but if you have suggestion to improve this procedure or also a different, better solution each suggestion is welcomed. ^_^

1 Comments:

Wow! Thanks you for the idea :D

March 30, 2017 at 2:26 AM comment-delete

Post a Comment