我有一个用QML创建gui的QT。我使用的是使用模型显示数据的自定义组件。在运行时,此模型将更改。但是没有反映出这些变化。
MyCustomComponent
{
property var myModel: [
{
icon: "qrc:/resources/my_icon1.png",
data: "Initial text",
},
{
icon: "qrc:/resources/my_icon2.png",
data: "Initial text",
}
]
model: myModel
property int myProp: 0
onMyPropChanged:
{
refreshModel()
}
function refreshModel()
{
console.error("refreshModel: before: myModel:" + myModel[0].data + ", model:" + model[0].data);
myModel[0].data = "alternate text"
console.error("refreshModel: after: myModel:" + myModel[0].data + ", model:" + model[0].data);
}
}
结果:
refreshModel: before: myModel:Initial text, model:Initial text
refreshModel: after: myModel:alternate text, model:Initial text
因此,在运行时myProp
发生变化时,将调用refreshModel
。但是model
本身保持不变,myModel
确实发生了变化。
直接更改模型而不是也不起作用。 (所以删除myModel中间属性)。
我需要做些什么不同的事情?
旁注:
最初我使用的是ListModel
+ ListElement
,但这还有其他问题,我正在寻找替代(ListElement: cannot use script for property value)
答案 0 :(得分:2)
查看Qt文档中有关var
type的内容。
值得注意的是,分配给var属性的JavaScript对象的常规属性的更改不会触发访问它们的绑定的更新。
因此,为了触发更新,您必须在修改模型后手动发出myModelChanged
信号。
function refreshModel()
{
console.error("refreshModel: before: myModel:" + myModel[0].data + ", model:" + model[0].data);
myModel[0].data = "alternate text"
myModelChanged()
console.error("refreshModel: after: myModel:" + myModel[0].data + ", model:" + model[0].data);
}
答案 1 :(得分:0)
实际上,修改myModel结构不会触发信号。我习惯了这种模式,它具有使用不可变结构的优点:
MyCustomComponent
{
function computeModel(initial)
{
return [
{
icon: "qrc:/resources/my_icon1.png",
data: initial ? "Initial text" : "alternate text",
},
{
icon: "qrc:/resources/my_icon2.png",
data: "Initial text",
}
];
}
model: computeModel(true)
property int myProp: 0
onMyPropChanged:
{
model = computeModel(false);
}
}
答案 2 :(得分:0)
正如其他答案已经指出的那样,JSON结构是一种变体类型。因此, modelChanged 信号仅在您将新值(新JSON)重新分配给属性的情况下才会触发。对结构的各个部分进行细微改动不会触发信号。
也请注意:在将此类变体模型用于您的ListView,也会遭受性能和可用性方面的缺点。即使您修改模型并手动触发信号,该视图也需要完整重绘。它只知道“ 模型中的某些东西发生了改变”。
为避免这种情况,您可以使用 JsonListModel 将JSON转换为实际的 ListModel 类型( QAbstractListModel 实现):
MyCustomComponent
{
property var myJson: [
{
id: 1,
icon: "qrc:/resources/my_icon1.png",
data: "Initial text",
},
{
id: 2,
icon: "qrc:/resources/my_icon2.png",
data: "Initial text",
}
]
model: JsonListModel {
source: myJson
keyField: "id"
}
property int myProp: 0
onMyPropChanged:
{
refreshModel()
}
function refreshModel()
{
myJson[0].data = "alternate text"
myJsonChanged() // emit changed signal, JsonListModel thus also updates
}
}
您可以找到有关JsonListModel及其用法here的更多详细信息。