如何使用索引访问 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
所以你的当前项目数总是设置
我想访问 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
所以你的当前项目数总是设置