我想了解 listmodel读写字段的功能,因此编写了以下测试代码
import QtQuick 2.15
import QtQuick.Controls 2.15
import Qt.labs.qmlmodels
//整体代码思路如下
ApplicationWindow {
visible: true
width: 400
height: 300
title: "修改listmodel数据, get方法和setproperty方法 结果不一样"
//定义view 设置model 和 delegate
ListView {
id: listview
anchors.fill: parent
spacing : 2
model: dataModel
clip: true
delegate: integerComponent
}
// 定义model字段以及字段值
ListModel {
id: dataModel
ListElement { intValue: 2 }
//此处略
}
// 定义 delegate 显示model数据 这里使用一个数值范围0-6的下拉菜单thebox
// 它会将每次选中的值实时反馈给datamodel的intValue字段
Component {
id: integerComponent
ComboBox {
id:thebox
required property int intValue
model: [ 0 ,1, 2, 3, 4, 5, 6 ] // 定义下拉显示数据
onActivated: {
case 1 : dataModel.get(0).intValue = thebox.model[currentIndex];
case 2 ;dataModel.setProperty
(thebox.index,"intValue",thebox.model[currentIndex])
}
}
//在窗口中心,用来显示intvalue字段的值
//这里text绑定了intvalue的值,按理说随着intvalue变化,text显示值会变化
Text {
id: text1
anchors.centerIn: parent
text: dataModel.get(0).intValue
font.pixelSize: 20
}
}
代码原理很简单,先使用combox下拉菜单修改intvalue字段的值,然后把这个intvalue绑定到Text组件,实时显示出来
预期效果:
case1 方法 与 case2 方法都能生效,intvalue的值会实时更新
实际情况:
使用get方法给intvalue赋值,根本不会实时更新绑定值,使用setproperty方法才正常
说明- listmodel获取字段值,修改字段值的方法
前面两种是我上述代码里已经提到的。。。case1和case2
case1: 使用get()方法更新字段值
listModel.get(0).intValue = 0;
采用诸如这样形式,更新字段intvalue。intvalue在model里的值可以更新,但是绑定值不会更新。
比如前面描述的代码中,text :datamodel.get(0).intvalue 这句,看起来text与intvalue建立了正确的绑定关系。但是text文本不会因为intvalue值变化而自动更新,依然显示上次的值。
case2: 使用setproperty方法改变字段值
listModel.setProperty(IntValueIndex,"intValue",ValueSeting)
调用形式如上所示,这个方法没什么问题,我就不展开讲了
总之,要想使得与目标字段值所有相关的绑定都生效,采用这种方法最为稳妥。这个是我使用多种方法,经过多次尝试,总结的经验。
case3: 使用required 获取字段值
这个方法简单介绍一下,给各位新手避个雷
定义委托组件时,可以在内部按照定义变量的规则,定义如下式子
required property int intValue
这样就能很方便地获取到,model中已经定义好的,相同名称的字段值。
这种方法是qt官方设定的机制,这里不细讲
这个方法当用来读取model数据时,没什么问题。
但是不要想通过这个变量,修改model对应位置的字段值。否则,竹篮打水一场空
其实际表现,等同这段伪代码。
int intvalue : listmodel.intvalue
很明显,此intvalue,非彼intvalue,两者是绑定关系,而非引用。
listmodel.intvalue值更新,intvalue的值会随之更新
intvalue的值更新,不会影响到listmodel.intvalue
总结
1.get方法更适合读取数据,不适合用来写值。
估计它返回的只是数据对象,缺少数据变化了的信号。因此不能自动更新与之绑定的值。
2. setproperty方法专门用来写入字段值。最安全的model写入方法
3.委托组件内用 required 定义的变量,不能算作直接引用了外部变量,彼此是绑定关系
因此用来读值可以,不能用来给model赋值