[英]QML ListView Acess To an Item of the delegate
this is my code:这是我的代码:
main.qml主要.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我的复选框.qml
CheckBox {
id : chk
width: 25
height: 25
}
i wanna check on of the Checkbox with the Button OnClicked ( for example when i click, i Check the ItemAtIndex 2), to do this i need to access to the Object of my listview, there is a function available since QT 5.13 Item itemAtIndex(int index) but i'm using QT 5.12, is there another way to do it?我想用按钮 OnClicked 检查复选框(例如,当我单击时,我检查 ItemAtIndex 2),为此我需要访问我的列表视图的 Object,自 QT 5.13 ItemAtIndex( int index) 但我使用的是 QT 5.12,还有其他方法吗? Thanks for your help谢谢你的帮助
Trying to manually modify an item in a ListView
is actually the wrong approach.尝试手动修改ListView
中的项目实际上是错误的方法。 If you have 1000 items in your list, ListView
is smart enough to not create 1000 delegate items.如果您的列表中有 1000 个项目, ListView
足够聪明,不会创建 1000 个委托项目。 Instead, it creates only as many as it needs for the visible region of the list and reuses them with different model data as you scroll up and down.相反,它只创建列表可见区域所需的数量,并在您上下滚动时将它们与不同的 model 数据一起使用。 So because of that, if you try to access the item at index 987 for instance, that item might not even exist.因此,例如,如果您尝试访问索引 987 处的项目,则该项目甚至可能不存在。
The better way to do handle this is to include the checked state in your model, and update that model when you want the item to change.处理此问题的更好方法是将选中的 state 包含在您的 model 中,并在您希望更改项目时更新该 model。
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
}
}
}
}
One way to achieve is creating a list of items.实现的一种方法是创建项目列表。 Add item to list onCompleted
and remove onDestruction
.将项目添加到列表onCompleted
并删除onDestruction
。 Or use onAdd
and onRemove
in ListView
.或者在ListView
中使用onAdd
和onRemove
。 Following code worked for me in 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;
}
}
}
}
Update: Removing item by splice(index, 1)
might disorder indexes of other items.更新:通过splice(index, 1)
删除项目可能会打乱其他项目的索引。 So I think assigning undefined
is a safer solution.所以我认为分配undefined
是一个更安全的解决方案。
Note: Don't use this solution if you don't really have to get the item itself, otherwise checkout @JarMan's answer, using model is the right way to go.注意:如果您真的不需要自己获取物品,请不要使用此解决方案,否则请查看@JarMan 的回答,使用 model 是 go 的正确方法。
You can Use itemAtIndex()
like intemAt()
in Repeater
.您可以像Repeater
中的itemAtIndex()
intemAt()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.