Storing, loading and working with dynamically created QML objects



  • Hi everyone

    I want to dynamically create multiple QML objects from a template file and be able to display or hide them on demand. I also want to be able to change their properties.

    For example I want to create a rectangle from a template that has a red background and change the background color to green.
    Then hide the first rectangle and create a second one and change the background color to blue.
    Now I want to hide the second one, and display the first one again.

    But my problem is, whenever I try to change the component of the Loader, it just loads the original template file (rectangle with red background)

    Since I'm relatively inexperienced with Qt, I tried it like this:
    My main.qml
    @import QtQuick 2.2
    import QtQuick.Controls 1.1

    ApplicationWindow {
    id: appWindow
    title: qsTr("Test")
    color: "white"
    width: 1600
    height: 900
    visible: true

    property var viewList: new Array
    
    function addView() {
        //create 2 components from a template file and store them in an array
        var component
        component = Qt.createComponent("WorkSpace.qml")
        viewList.push(component)
        component = Qt.createComponent("WorkSpace.qml")
        viewList.push(component)
    
        //load first component to a loader and change color to green
        workspace.sourceComponent = viewList[0]
        workspace.children[0].color = "green"
    
        //load second component to a loader and change color to blue
        workspace.sourceComponent = viewList[1]
        workspace.children[0].color = "blue"
    
        //reload first component
        workspace.sourceComponent = viewList[0]
    }
    
    //BUTTON
    Rectangle {
        height: 32
        width: 32
        color: "green"
    
        Text {
            text: "+"
            font.pixelSize: 24
            font.bold: true
            color: "black"
            anchors.horizontalCenter: parent.horizontalCenter
            anchors.verticalCenter: parent.verticalCenter
        }
    
        MouseArea {
            anchors.fill: parent
    
            onClicked: {
                addView()
            }
        }
    }
    
    //WORKSPACE
    Loader {
        id: workspace
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.verticalCenter: parent.verticalCenter
    }
    

    }
    @

    WorkSpace.qml
    @import QtQuick 2.2

    Rectangle {
    visible: true
    width: 800
    height: 600
    color: "red"
    }
    @

    I would expect to see a green rectangle when I click the button, but I end up seeing the red one. I guess my main problem is understanding in what scope these objects exist and how to access them.

    Anyone can point me in the right direction of the best practice to dynamically create qml objects, hide and show them on demand and changing their properties persistently?

    Thanks in advance!


  • Moderators

    Hi,

    Any specific reason you want to use createComponent ?
    You can instead directly assign a QML to source of the Loader
    For eg.
    @
    workspace.source = "WorkSpace.qml"
    console.log(workspace.item.color) //to access the properties, use item
    @

    More "here":http://qt-project.org/doc/qt-5/qml-qtquick-loader.html#source-prop.



  • The problem is, that I want multiple instances of the WorkSpace.qml and change their properties independently.

    E.g. I want 3 instances of WorkSpace.qml. One with a green, one with a blue and one with a yellow color.

    I've managed to solve this now by using createComponent and then using component.createObject and storing the result of this in an array.

    Then I just display the currently active workspace and hide all the others. This way, each instance of the WorkSpace.qml is kept in memory during run time and I can change all their properties independently.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.