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.
NOTE: in case you are looking for a specific splash screen solution for Android check this post.
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. ^_^
Comments
Post a Comment