There is a way to do this using the QQuickWindow afterSynchronizing signal:
import QtQuick 2.4 import QtQuick.Controls 1.3 ApplicationWindow { width: 400 height: 400 visible: true Component.onCompleted: print(Qt.formatDateTime(new Date(), "mm:ss:zzz"), "QML loaded") onAfterSynchronizing: { print(Qt.formatDateTime(new Date(), "mm:ss:zzz"), "Window content rendered") if (!loader.item) { loader.active = true } } Item { anchors.fill: parent BusyIndicator { running: !loader.item anchors.centerIn: parent } Loader { id: loader active: false anchors.fill: parent sourceComponent: Text { wrapMode: Text.Wrap Component.onCompleted: { for (var i = 0; i < 500; ++i) { text += "Hello, "; } } } } } }
The idea is to use Loader to control when an expensive operation occurs. You can also use a dynamically loaded component via Qt.createQmlObject() or Qt.createComponent() to dynamically load the component into a separate file.
If you run this example, you will see that you get the following output:
qml: 58: 12: 356 loaded with QML
qml: 58: 12: 608 The contents of the window are displayed.
We use the QQuickWindow afterSynchronizing signal to know when the contents of the window are displayed and only act on it first (via if (!loader.item) ).
When the signal is initially emitted, we can be sure that the BusyIndicator started the animation, so the user will really see the turn icon.
As soon as Loader finishes loading the text, its item property will not be null, and the BusyIndicator will disappear.
Mitch source share