Home > Enterprise >  How To Place Children Items of my Custom Item at my desired Location? (QML)
How To Place Children Items of my Custom Item at my desired Location? (QML)

Time:09-29

Assuming I want to create my CustomItem

//MyCustomItem.qml
RowLayout{
        spacing: 0

        Image{
            id: divider
            source: "qrc:/screen_header/vertical_divider_screen_header.png"

        }


        Item{ //THIS PART HERE SHOULD ALWAYS BE THE CHILDREN ITEMS 
            id:mid_item_TEXT_OR_IMAGE
            Layout.alignment: Qt.AlignHCenter
        }

        Image{
            id: divider2
            source: "qrc:/screen_header/vertical_divider_screen_header.png"

        }
}

I want to use this CustomItem and every children should be automatically be placed inside "Item" but the Layout.alignment should persist.

For Example

Placing an image inside would result in

  //main.qml
  MyCustomItem{
            Image{
                source: "qrc:/test.png"
            }  
        }

enter image description here

Placing a Text inside would result in

   MyCustomItem{
            Text{
                text: "AUTO"
            }  
        }

enter image description here

How can I achieve this?

CodePudding user response:

You can use a default property to automagically direct the Image/Text into mid_item_TEXT_OR_IMAGE with the following code:

default property alias children: mid_item_TEXT_OR_IMAGE.data

Note that this allows multiple elements inside MyCustomItem (including non-visual ones). If you don't want this, you can use a Control (Qt doc) instead of mid_item_TEXT_OR_IMAGE and alias to contentItem.


Btw, the Layout.alignment: Qt.AlignHCenter that you really want will not work, since the RowLayout will assign the Item a place on the horizontal axis based on the items. It does work for Qt.AlignVCenter since that is perpendicular to the layout direction.

With the following code you can center all contents in the middle like in your images:

RowLayout {
    default property alias data: mid_item_TEXT_OR_IMAGE.data

    Rectangle { //replace with your Divider.png
        width: 1
        Layout.fillHeight: true
        color: "white"
    }

    Item {
        Layout.fillWidth: true
        implicitWidth:  mid_item_TEXT_OR_IMAGE.childrenRect.width
        implicitHeight: mid_item_TEXT_OR_IMAGE.childrenRect.height

        Item{ //THIS PART HERE SHOULD ALWAYS BE THE CHILDREN ITEMS
            id:mid_item_TEXT_OR_IMAGE
            width: childrenRect.width
            height: childrenRect.height
            anchors.centerIn: parent
        }
    }

    Rectangle {
        width: 1
        Layout.fillHeight: true
        color: "white"
    }
}

By using the implicitWidth and implicitHeight, the RowLayout will also grow according to the content that you put in. The other way around also works, you can give width/height for MyCustomItem on the place where you use it

CodePudding user response:

I think what you're looking for is a default property. If you define your default property to be the data field of your Item, then by default all child objects will become children of that Item.

//MyCustomItem.qml
RowLayout{
        default property alias contents: mid_item_TEXT_OR_IMAGE.data

        Item{
            id:mid_item_TEXT_OR_IMAGE
            Layout.alignment: Qt.AlignHCenter
        }
}
  • Related