如何使用索引访问 ListView 中的委托属性

How to access delegate properties in ListView using index

我想访问 ListView 中的委托属性。我试过 contentItem 但有时是 undefined.

这是我的代码:

ListModel{
            id: modeldata
            ListElement{
                name:"don"
                rank:1
            }
            ListElement{
                name:"shan"
                rank:2
            }
            ListElement{
                name:"james"
                rank:3
            }
            ListElement{
                name:"jeggu"
                rank:4
            }
        }
        Component{
            id: delegateitem
            Row {
                property int count: rank
                Rectangle{
                    width: 100
                    height: 50
                    Text{
                        anchors.centerIn: parent
                        text: name
                    }
                }
            }
        }
        ListView{
            id: listview
            focus: true
            anchors.fill: parent
            model: modeldata
            delegate: delegateitem
            onCurrentIndexChanged: {
        console.log("position",currentIndex)
        console.log("property",contentItem.children[currentIndex].count);
            }
        }

问题1位置输出无效

qml: position 0
qml: property 1
qml: position 1
qml: property undefined
qml: position 2
qml: property 2
qml: position 3
qml: property 3

首先:如果您尝试从列表外部访问列表元素,这是一个很好的指标,表明您应该重新考虑您的设计。

现在解决方案:列表视图的子项多于其项。例如,您可以通过定义 属性 "property string type: "myType" " 来过滤掉它们。然后通过遍历子项来查找项目,并且只获取类型 属性 等于 "myType" 的项目。 这有点骇人听闻,但您一开始真的不应该这样做。

@Teimpz 没有真正解释清楚。特别是因为有一堆 qt 项目和 ubuntu touch qml 示例和用例,您可以使用 javascript 管理动态创建的列表元素,这就是为什么它们具有 javascript 方法和属性

在 QML 中,父概念多于子概念,这在 html 中很常见。在更大的项目中,建议(正如您在 qt 示例和文档 http://doc.qt.io/qt-5/qtqml-javascript-expressions.html#functions-in-imported-javascript-files 中看到的那样)将 js 逻辑与 qml 元素分开,这样您就可以从外部访问和管理元素,而不是用 js 逻辑污染您的 qml 元素,但不是以寻找子元素的方式,而是公开您需要的子元素。

在你的情况下,你应该只使用 currentItem,就像你使用 currentIndex 一样,所以 currentItem.count 会给你你需要的。 如果您根本不需要当前项目,您可以直接从模型访问元素:

modelData.get(currentIndex).count,或listview.model.get(currentIndex).count

至于@Teimpz 提到的 hack 也是一个不好的例子。当您有更复杂的要求并希望在委托中包含特定元素时,每个委托都有 ListView.isCurrentItem 属性 可以附加和检查。这意味着您可以将 属性 var myTargetItem 添加到列表视图,如果该委托是当前的 http://doc.qt.io/qt-5/qml-qtquick-listview.html#isCurrentItem-attached-prop

,则可以将其从子元素设置为您想要的任何元素

您当然可以为任何类型的事件执行此操作,也许是 activeFocus,因此您只能引用 activeFocused 项目。

这再次使您能够仅公开需要的元素,而无需任何高级逻辑或循环。将其与信号相结合,您可以创建非常复杂但干净的界面,而无需搜索子项。

所以最后可能不太好但仍然比搜索元素更好的是将 property int currentItemCount: 0 添加到列表视图。然后在委托(行元素)中添加 property bool isCurrentItem: ListView.isCurrentItem 所以你在委托中得到 onIsCurrentItemChanged 信号,你可以在其中执行以下操作: onIsCurrentItemChanged: if(isCurrentItem) listview.currentItemCount = count 所以你的当前项目数总是设置