如何将附加属性添加到子项

How to put attached properties to child item

假设我有这样的组件

RowLayout {
    MyItem {
        Layout.fillWidth: true
        Layout.fillHeight: true
        ... // other properties
    }
    MyItem {
        Layout.fillWidth: true
        Layout.fillHeight: true
        ... // other properties
    }
}

其中 MyItem.qml 是这样定义的

Rectangle {
    ... // other properties
    // Layout.fillWidth: true
    // Layout.fillHeight: true
}

我可以把 Layout.fillWidth 放到 MyItem 中,这样我就不需要在 RowLayout 中重复它了吗?

是的,你可以这样做,但是当你决定在没有附加 属性 命名为 Layout.fillWidth 的上下文中使用该组件时,它会以错误结束,或者更一般地说, 每当您决定不将其用作布局中的顶部元素时。

Can I put Layout.fillWidth to MyItem, so I don't need to repeat it in RowLayout ?

我觉得这个问题里面有答案:如果你不想重复,就用Repeater类型。文档指出

Items instantiated by the Repeater are inserted, in order, as children of the Repeater's parent. The insertion starts immediately after the repeater's position in its parent stacking list. This allows a Repeater to be used inside a layout.

文档中的示例使用 Row,但同样的方法可以应用于其他布局,例如RowLayout。实际上,根据 Repeater 性质 ("insert items inside parent"),它适用于任何具有附加属性的类型。

这是一个例子。假设我们已经定义了一个 Example 类型。

import QtQuick 2.5

Rectangle {
    property alias text: inner.text
    color: "steelblue"

    Text {
        id: inner
        anchors.centerIn: parent
        font.pixelSize: 30
    }    
}

我们可以将布局属性添加到 Repeater 中的 Example 类型,例如:

import QtQuick 2.5
import QtQuick.Window 2.2
import QtQuick.Layouts 1.1

Window {
    id: window
    width: 600
    height: 400
    visible: true

    RowLayout {
        id: row
        anchors.fill: parent

        Repeater {
            model: 6               

            delegate : Example {
                text: index
                Layout.fillWidth: true    // layout options added in the delegate
                Layout.fillHeight: true
                Layout.alignment: Qt.AlignCenter
                Layout.maximumWidth: parent.width / model.length
            }
        }
    }
}

Repeatermodel 属性 可以是字符串数组,也可以是其他模型,和往常一样。

这种方法足够灵活,可以组合多个 Repeater 来创建更复杂的结构。例如,请参见以下示例,其中 Text 用于在 GridLayout 内填充屏幕:

import QtQuick 2.5
import QtQuick.Window 2.2
import QtQuick.Layouts 1.1

Window {
    id: window
    width: 600
    height: 400
    visible: true

    GridLayout {
        id: grid
        anchors.fill: parent
        rows: 2
        columns: 6

        Repeater {
            model: grid.columns
            Text {
                Layout.fillWidth: true
                Layout.fillHeight: true
                Layout.row: 0
                Layout.column: index
                verticalAlignment: Text.AlignVCenter
                horizontalAlignment: Text.AlignHCenter
                text: index + 1    // index of the repeater as text
            }
        }

        Repeater {
            model: grid.columns
            Text {
                Layout.fillWidth: true
                Layout.fillHeight: true
                Layout.row: 1
                Layout.column: index
                verticalAlignment: Text.AlignVCenter
                horizontalAlignment: Text.AlignHCenter
                text: index + 7
            }
        }
    }
}