Search code examples
qtqmlqt5qtquick2qt-quick

How to display the assigned property component in QML QT5?


In Main.qml

Item {
    id:windowId
    width:200;height;200;
    Page{
      style: MyStyle{
           id:myStyleId
           background: Rectangle{
                width:30;height;30;color:"blue"
           }  
           background2: Rectangle{
                width:10;height;10;color:"green"
           }             
      }
    }
}

In Page.qml

Item {
    id: pageId
    property MyStyle style
    //How to display the style property
}

In MyStyle.qml

 Item {
    id: mystyleId
    property Rectangle background
    property Rectangle background2
    //How to display the background and background2 properties
 }

As you can see above I have style property assigned with MyStyle while creating Page

How do I display the style property inside Page and background property insode MyStyle.

I have tried doing like this in Page.qml and also similarly in MyStyle.qml, but still it is not displaying without any errors

Item {
    property alias style : loader.sourceComponent

    Loader { id: loader }
}

A rough drawing at the end: (1) Page.qml; (2,3) Rectangles from Style.qml

Main


Solution

  • Items that are assigned to a property won't get their parent set.

    When you have the notion:

    ItemA {
        ItemB {}
    }
    

    ItemB will be automatically set to be part of ItemA.children and ItemB.parent will be set to ItemA.

    This does not happen, if you write:

    ItemA {
        property Item someItem: ItemB {}
    }
    

    Here you leave ItemB.parent to be null, and ItemB won't appear in ItemA.children.


    This means, you need to set this manually, by either adding it to the desired parents children-property, or by setting the parent-property of the child.

    ItemA {
        id: itmA
        property Item someItem: ItemB { parent: itmA }
    }
    

    makes ItemB to appear.


    As, most likely, you don't want to write that everytime you put something in that property you can use the onPropertyChanged-slot to do this:

    ItemA {
        property Item someItem
        onSomeItemChanged: someItem.parent = this
    }
    

    In this case, when you assign a new Item to someItem the former one won't lose the parent however, and will still be drawn at the same position. So you might also want to create a connection to remove the parent again. For this we will create a closure to store the reference for the connection:

    Item {
        id: root
        property Item someItem
        onSomeItemChanged: {
            console.log('SomeItem changed')
            someItem.parent = root
            this.onSomeItemChanged.connect(generateClosure(someItem))
        }
    
        function generateClosure(smeItm) {
            return function() { if (someItem !== smeItm) { smeItm.parent = null } }
        }
    }
    

    or if you want to restore the original parent we use this function for the closure:

    function generateClosure(smeItm, originalParent) {
        return function() { if (someItem !== smeItm) { smeItm.parent = originalParent } }
    }
    

    and make sure, we call it as long as we still have a reference to the original parent.