axolotlKing0722
axolotlKing0722

Reputation: 289

In QML, how to set properties for every child of a Layout?

I'm new to QML and I want to place a bunch of itmes in a column. Lets say I have a custom component called MyComponent which is basically a rounded Rectangle with text in it.

I want to put e.g. 5 of those MyComponent elements in a column like this:

ColumnLayout {
    MyComponent { text: "a" }
    MyComponent { text: "b" }
    MyComponent { text: "c" }
    MyComponent { text: "d" }
    MyComponent { text: "e" }
}

I cannot use a Repeater as each element should have a different text. Now, let's say I want to stretch these elements horizontally. In a ColumnLayout, i guess you have to do it like this:

ColumnLayout {
    MyComponent {
        text: "some text"
        Layout.fillWidth: true
    }
}

But this means I'd have to do this manually for every single MyComponent, as setting Layout.fillWidth: true for the ColumnLayout does not work. So how can I set something like the default layout for child elements? How can I just say that every element in the ColumnLayout should be stretched horizontally?

(and, btw, is there any reason why in QML child elements position themselves inside their parent elements, and not vice-versa? Like, in CSS, when I have a flex column, I configure the basic positioning inside the flex container, not the flex items. Like, when I want every item to be stretched horizontally, I could just say align-items: center. And to me this approach makes a lot more sense because it follows the layout hierarchy - the container is one level above the child, so it controls how to position the child, not the other way. But that might also be just my subjective opinion)

Upvotes: 1

Views: 53

Answers (1)

Stephen Quan
Stephen Quan

Reputation: 26214

This statement

I cannot use a Repeater as each element should have a different text

is incorrect, since, as Soheil Armin points out, the different text can be put in the model of the Repeater (either a JS array or a ListModel will work). As to declaring a style where Layout.fillWidth: true is applied to MyComponent, we can do that with a derivative component, say, MyComponent2, e.g.

ColumnLayout {
    Repeater {
        model: ["a","b","c","d","e"]
        delegate: MyComponent2 { text: modelData }
    }
}

// MyComponent2.qml
import QtQuick.Layouts
MyComponent {
     Layout.fillWidth: true
}

// MyComponent.qml
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Label {
    Layout.margins: 10
    background: Item {
        Rectangle {
            anchors.fill: parent
            anchors.margins: -8
            radius: 10
            border.color: "black"
       }
    }
}

You can Try it Online!

As to your subsequent point about element types, that isn't demonstrated in your question, but, if it were, it is covered by @smr's comment about DelegateChooser.

Upvotes: 2

Related Questions