QML ListView 访问委托的项目
Posted
技术标签:
【中文标题】QML ListView 访问委托的项目【英文标题】:QML ListView Acess To an Item of the delegate 【发布时间】:2021-01-28 21:10:00 【问题描述】:这是我的代码:
main.qml
ApplicationWindow
visible: true
width: 640
height: 480
title: qsTr("Scroll")
Button
id:btn
x : 100
y : 100
text: "Click Her to check one of the checkbox! "
ScrollView
width: 40
height: parent.height
ListView
id : view
width: parent.width
leftMargin: 5
model: 20
delegate:
MyCheckBox
MyCheckBox.qml
CheckBox
id : chk
width: 25
height: 25
我想用 OnClicked 按钮检查复选框(例如,当我单击时,我检查 ItemAtIndex 2),为此我需要访问我的列表视图的对象,自 QT 5.13 起就有一个可用的功能项目 itemAtIndex(int index) 但我使用的是 QT 5.12,还有其他方法吗?感谢您的帮助
【问题讨论】:
【参考方案1】:尝试手动修改ListView
中的项目实际上是错误的方法。如果您的列表中有 1000 个项目,ListView
足够聪明,不会创建 1000 个委托项目。相反,它只为列表的可见区域创建所需的数量,并在您上下滚动时将它们与不同的模型数据一起使用。因此,例如,如果您尝试访问索引 987 处的项目,则该项目甚至可能不存在。
处理此问题的更好方法是在模型中包含选中状态,并在您希望项目更改时更新该模型。
ApplicationWindow
visible: true
width: 640
height: 480
title: qsTr("Scroll")
ListModel
id: myModel
ListElement
isChecked: false
ListElement
isChecked: false
ListElement
isChecked: false
ListElement
isChecked: false
ListElement
isChecked: false
Button
id:btn
x : 100
y : 100
text: "Click Her to check one of the checkbox! "
// Check index 3
onClicked:
myModel.set(3, "isChecked": true)
ScrollView
width: 40
height: parent.height
ListView
id : view
width: parent.width
leftMargin: 5
model: myModel
delegate: MyCheckBox
checked: isChecked
【讨论】:
【参考方案2】:实现的一种方法是创建项目列表。将项目添加到列表 onCompleted
并删除 onDestruction
。或者在ListView
中使用onAdd
和onRemove
。
以下代码在online compiler 中为我工作:
import QtQuick 2.3
import QtQuick.Controls 2.12
ApplicationWindow
visible: true
width: 640
height: 480
title: qsTr("Scroll")
Button
property int checkBoxIndex: 5
id:btn
x : 100
y : 100
text: "Click Her to check one of the checkbox! "
onClicked:
var item = view.items[checkBoxIndex];
if (item)
item.toggle();
else
console.log("Item not found at index: " + checkBoxIndex);
ScrollView
width: 40
height: parent.height
ListView
property var items: []
id : view
width: parent.width
leftMargin: 5
model: 20
delegate: CheckBox
id : chk
width: 25
height: 25
Component.onCompleted: view.items[index] = chk;
Component.onDestruction: view.items[index] = undefined;
更新:
删除splice(index, 1)
的项目可能会导致其他项目的索引混乱。所以我认为分配undefined
是一个更安全的解决方案。
注意: 如果您真的不需要自己获取项目,请不要使用此解决方案,否则请查看@JarMan 的答案,使用模型是正确的方法。
【讨论】:
以上是关于QML ListView 访问委托的项目的主要内容,如果未能解决你的问题,请参考以下文章
如何在 QML 中访问 ListView 的 ListModel 的 ListElement 的映射委托数据?
如何从QML中的GridView或ListView获取实例化的委托组件