如何在委托中对齐 QML 组件

How to align QML components in a delegate

我想将我的 phone 个数字列表与左侧的一个字段 ("name") 和右侧的另一个字段 ("phone") 对齐。但是,当尝试在委托内绑定锚点属性时,它表示委托对象不是 ListView 组件的父对象。我如何从委托到达其他组件?

这是我的 QML 代码:

import QtQuick 2.7
import QtQuick.Controls 2.0

Item {
    id: enclosing_area
    width: 500
    height: 300
    ListModel {
        id: dataModel
        ListElement {
            name: "John Smith"
            phone: "1111-1111"
        }
        ListElement {
            name: "Peter Poter"
            phone: "2222-2222"
        }
        ListElement {
            name: "Anna Lasalle"
            phone: "3333-3333"
        }
    }

    ListView {
        id: list
        width: enclosing_area.width
        height: enclosing_area.height
        model: dataModel
        delegate: Rectangle  {
            width: enclosing_area.width
            border.color: "red"
            Label {
                text: name
                anchors.left: list.left
            }
            Label {
                text: phone
                anchors.right: list.right
            }
        }
   }
}

qmlscene 产生以下错误:

file:///LViewTest.qml:36:13: QML Label: Cannot anchor to an item that isn't a parent or sibling.
file:///LViewTest.qml:32:13: QML Label: Cannot anchor to an item that isn't a parent or sibling.
file:///LViewTest.qml:36:13: QML Label: Cannot anchor to an item that isn't a parent or sibling.
file:///LViewTest.qml:32:13: QML Label: Cannot anchor to an item that isn't a parent or sibling.
file:///LViewTest.qml:36:13: QML Label: Cannot anchor to an item that isn't a parent or sibling.
file:///LViewTest.qml:32:13: QML Label: Cannot anchor to an item that isn't a parent or sibling.

第 32 行和第 32 行是 "anchors.left" 和 "anchors.right" 语句。 在我的案例中,如何从委托绑定到另一个对象中的属性?

利用锚点而不是尝试硬编码子元素的大小以匹配其父元素。这将使您能够一直使用锚点。 (同样,使用锚边距而不是硬编码的 x,y 值)。锚点还有很多其他好处。

    ListView {
        id: list
        anchors.fill: parent
        model: dataModel
        delegate: Rectangle  {
            anchors.left: parent.left
            anchors.right: parent.right
            height: 50       // you need a height otherwise all rows are on the same line
            border.color: "red"
            Label {
                text: name
                anchors.left: parent.left
            }
            Label {
                text: phone
                anchors.right: parent.right
            }
        }
   }
}

最初:

按照惯例称呼您的 enclosing_area root
其次,如果你不锚定到兄弟姐妹,不要使用你想要锚定到的对象的id,而是使用parent.

这可以防止您出现错误,因为 - 您正在尝试做的 - 不是锚定到 Label 的父级,而是锚定到它们的 parentparent.
Labelparent 将是 delegate 中的 Rectangle

ListView {
    id: list  // <- This is not the parent of the Labels, but of the delegateRectangle
    width: enclosing_area.width     // works
    height: enclosing_area.height   // works
    // anchors.fill: parent         <- would do the same, more flexible, and only one line.
    model: dataModel
    delegate: Rectangle  {
        id: delegateRectangle // <--- This is the parent of the two Labels
        width: enclosing_area.width
        height: 30 // <- a heightis necessary. 
                   // As the objects are repositioned you need to set it explicitely
                   // and can't use anchoring. You could use the
                   // implicit height of it's children, to make it nice
        border.color: "red"
        Label {
            text: name
            anchors.left: delegateRectangle.left // this would work instead.
                                                 // list.left woudl try to anchor to the 'grandparent'
        }
        Label {
            text: phone
            anchors.right: parent.right // this would be the reccomended way.
                                        // Would also anchor to delegateRectangle
        }
    }
}

为什么您更喜欢锚定到 parent 而不是 parentid
该对象(几乎)总是有一个可视父对象,但这个可视父对象可能会改变。要么是因为您稍后在代码中添加了一个额外的层 - 或者甚至在运行时通过重新设置它的父级。所以你总是需要更新锚点。
因此,锚定到 parent 可以解决一个简单的错误。