Search code examples
qtqmlprogress-barqtquickcontrols

QML progress bar is NOT showing up on UI


I have this QML progress bar:

import QtQuick.Controls 2.0 as QQC20

Item {
    QQC20.ProgressBar {
        id: progressbar_id
        visible: false // even if "true", the progress bar does NOT show up on UI
        from: editorScene.progressbarMin
        to: editorScene.progressbarMax
        value: editorScene.progressbarVal

        onValueChanged: {
            console.log("Progressbar value changed: ", progressbar_id.value)
        }
        onVisibleChanged: {
            console.log("Progressbar visibility chanaged: ", progressbar_id.visible)
        }
    }
}

I can confirm that the progress bar value and visibility are changed by the methods onValueChanged and onVisibleChanged.

However, the problem is that the progress bar does NOT show up on the UI! How can I actually show the progress bar on the UI? Can anybody give me a hint?


Solution

  • Right now, all you're doing is creating a QML type which you can use as part of your API. To actually see it, you need to create an instance of it under a ApplicationWindow or Window (or anything else equivalent, e.g. Canvas or Felgo's GameWindow).

    There are two ways you can accomplish this. You can

    1. Directly add your item as a child of a window.
    2. Put your item in a separate file, and create an instance of that file under a window.

    Lé Code

    Method 1: Directly Adding as Child

    Directly insert your codeblock as a child of an ApplicationWindow.

    // Main.qml
    import QtQuick 2.0             // for `Item`
    import QtQuick.Window 2.0      // for `ApplicationWindow`
    import QtQuick.Controls 2.0    // as QQC20 // no need to label a namespace unless disambiguation is necessary
    
    ApplicationWindow {
    
        width: 480   // set the dimensions of the application window
        height: 320
        
        // here's your item
        Item {
            anchors.centerIn: parent   // place in centre of window
            
            ProgressBar {
                id: progressbar_id
                
                anchors.horizontalCenter: parent.horizontalCenter // horizontally align the progress bar
                
                from: 0    // don't know what editorScene is
                to: 100    // so I'm using raw values
                value: 5
        
                onValueChanged: {
                    console.log("Progressbar value changed: ", progressbar_id.value)
                }
                onVisibleChanged: {
                    // side note: I'm not getting any output from this handler
                    console.log("Progressbar visibility chanaged: ", progressbar_id.visible)
                }
            }
        }
        
        // provide user-interaction for changing progress bar's value
        MouseArea {
            anchors.fill: parent            // clicking anywhere on the background
            onClicked: progressbar_id.value += 5;   // increments the progress bar
                                                    // and triggers onValueChanged
        }
    }
    

    Method 2: Using a Separate File

    Save your item into a new qml file.

    // MyProgressBar.qml
    import QtQuick 2.0              // for `Item`
    import QtQuick.Controls 2.0     // for `ProgressBar`
    
    // here is your item, it has grown up to be in a file of its own 🚼
    Item {
    
        property alias value: progressbar_id.value  // for user-interaction
    
        ProgressBar {
            id: progressbar_id
            
            anchors.horizontalCenter: parent.horizontalCenter  // centre horizontally
            
            from: 0
            to: 100
            value: 5
    
            onValueChanged: {
                console.log("Progressbar value changed: ", progressbar_id.value)
            }
            onVisibleChanged: {
                console.log("Progressbar visibility chanaged: ", progressbar_id.visible)
            }
        }
    }
    

    Note that you still need the import statements.

    Then call it from a window in Main.qml. We'll use an ApplicationWindow here.

    // Main.qml
    import QtQuick 2.0
    import QtQuick.Window 2.0    // for `ApplicationWindow`
    
    // import "relative/path/to/progressbar"  // use this if MyProgressBar.qml is not in the same folder as Main.qml
    
    ApplicationWindow {
    
        width: 480
        height: 320
        
        MyProgressBar {
             id: progressbar_id
        }
        
        MouseArea {
            anchors.fill: parent
            onClicked: progressbar_id.value += 5;
        }
    }
    

    If your qml files aren't in the same directory, make sure you add an import "relative/path" at the top of the Main.qml file among the other import statements.

    For example, if

    • Your Qml project is in /Users/Lorem/Project,
    • The full path to your Main.qml is /Users/Lorem/Project/qml/Main.qml, and
    • The full path to your MyProgressBar.qml is /Users/Lorem/Project/qml/myControls/MyProgressBar.qml...

    Then use import "myControls" in Main.qml to import the items from the myControls subdirectory. Remember, you only need to import the directory, not the file itself.

    Result

    This is what the result resembles when I run it from a macOS.

    At startup.

    At startup.

    After 3 clicks on the background.

    After 3 clicks on the background.

    There is also console/debug output after each click:

    Progressbar value changed: 10
    Progressbar value changed: 15
    Progressbar value changed: 20