QML Progress Bar doesn't move

1.1k Views Asked by At

I am using QT v5.12.6 and in my application i am planning to use Progress Bar during application bootup for around 15secs. In this 15secs operations like:

  1. QML components creation.
  2. connection with the server.
  3. Other bootup operations will be running in the background.

Once, all the bootup operation is done i will hide my splash screen which is just a Rectangle which includes Loading text with a progress bar. For this 15 secs i will be incrementing the progress bar but the progress bar doesn't increment/move for some 10 secs. It looks like it is hanged, but if i use a busy indicator it starts to rotate. Unfortunately, i can't use busy indicator component as i need a look and feel like a progress bar.

My application runs on a embedded platform which has low end processor and very less RAM speed. I am assuming this problem is due to the Load on the UI as many components is getting created.

Is there any difference between busy indicator and Progress bar and also any suggestions on how to handle UI load on the bootup ?

Edit 1: Added an example. I have tried my level best to mimic the problem. In this example both the busyindicator and Progress bar is getting stuck for sometime. But in the embedded device Busy indicator works but no idea how. After running the application Please click on Click Me button.

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.3

Window {

    property int pbValue:0
    visible: true
    width: 500
    height: 400
    title: qsTr("Hello World")

    Rectangle{
        id: mySplashScreen
        anchors.fill: parent

        ProgressBar{
            id: pBar
            height: 20
            width: parent.width
            anchors.bottom: parent.bottom
            from:0
            value : pbValue
            to:30
        }

        BusyIndicator{
            anchors.right: parent.right
            running: (pbValue < pBar.to +1)
        }

        Button{
            text: "click me"
            onClicked: {
                //Create component equivalent to my application which has "n"
                //number of components like buttons, combobox, chart view etc.
                //Here just creating the rectangle more number of times.
                for(var i = 0 ; i < 15000 ;i++) //HINT : Increase/decrease the value if problem is not seen
                {
                    var comp = mycomp.createObject(mySplashScreen)
                }
            }
        }
    }

    Timer{
        id:timer
        interval: 250
        running: (pbValue < pBar.to +1)
        onTriggered: {
            pbValue += 1;
        }
    }

    Component{
        id:mycomp
        Rectangle{
            width: 200
            height: 200
            color: "green"
        }
    }
}
1

There are 1 best solutions below

2
On

Move your object creation code into a separate Timer with a small interval, and rather than creating all of the objects at once, create them maybe 50 at a time every 25 MS or something.

This will allow for the main event loop to process other things like the animations for busy indicator while its loading.

Here's one way to go about implementing this

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.3

Window {

    property int pbValue: 0
    visible: true
    width: 500
    height: 400
    title: qsTr("Hello World")

    Rectangle {
        id: mySplashScreen
        anchors.fill: parent

        ProgressBar {
             // changed handling of progress bar
            id: pBar
            height: 20
            width: parent.width
            anchors.bottom: parent.bottom
            from: 0
            value: compList.length // bind this value 
            to: 15000
        }

        BusyIndicator {
            anchors.right: parent.right
            running: (pbValue < pBar.to + 1)
        }

        Button {
            text: "click me"
            onClicked: {

                timer.running = true
            }
        }
    }

    property var compList: [] // created property to store all created components to track what has been done
    Timer {
        id: timer

        interval: 25
        running: false
        repeat: true
        onTriggered: {
            
            for (var i = 0; i < 50; i++) {
                var comp = mycomp.createObject(mySplashScreen) // moved component into timer
                compList.push(comp) // added component to huge list of components for tracking
            }

            pbValue = compList.length
            if ((pbValue >= 15000)) {
                timer.running = false
                console.log("All components completed")
            }
        }
    }

    Component {
        id: mycomp
        Rectangle {
            width: 200
            height: 200
            color: "green"
        }
    }
}