QML更新Json模型
我有一个QT,它的gui是用QML创建的。我正在使用一个自定义组件,它使用一个模型来显示数据。在运行时,此模型将发生更改。然而,这些变化并未反映出来QML更新Json模型,json,qt,qml,Json,Qt,Qml,我有一个QT,它的gui是用QML创建的。我正在使用一个自定义组件,它使用一个模型来显示数据。在运行时,此模型将发生更改。然而,这些变化并未反映出来 MyCustomComponent { property var myModel: [ { icon: "qrc:/resources/my_icon1.png", data: "Initial text", }, { i
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
。然而,模型
本身保持不变,myModel
确实发生了变化
直接更改模型而不更改也不起作用。(因此,删除myModel中间的属性)
我需要做什么不同的事情
旁注:
最初我使用的是
ListModel
+ListElement
,但这还有其他问题,我正在寻找替代的(ListElement:cannot use script for property value)
事实上,修改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);
}
}
看看Qt文档中关于的内容 需要注意的是,分配给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);
}
正如其他答案已经指出的那样,JSON结构是一种变体类型。因此,modelChanged信号仅在重新为属性分配新值(新JSON)时才会激发。对结构的某些部分进行微小的更改不会触发信号 另请注意:在ListView中使用这种变体模型时,您也会遇到性能和可用性方面的缺陷。即使修改模型并手动触发信号,视图也需要完全重新绘制。它只知道“模型中的某些东西发生了变化” 为了避免这种情况,您可以使用JsonListModel将JSON转换为实际的ListModel类型(QAbstractListModel实现):
您可以找到有关JsonListModel及其用法的更多详细信息。简而言之,您说必须重新分配模型。删除和创建模型对象以更新单个字段听起来效率很低。是的,我不记得重新分配同一对象是否会触发信号。尝试不变性而不是过早优化。另一种方法是将
ListModel
与setProperty
或set
function@GrecKo确实如此,但使用ListModel限制了我的使用。我希望能够使用我的模型中的定义:“ListEng:不能使用脚本来处理属性值”。如果在C++中实现了模型(例如使用代码> QuastListMeals),模型的更改将反映到UI中。这在这里不起作用的原因是,简单列表没有用于更改数据的信号。这似乎确实起到了作用。这仅在使用额外的var属性时有效?您不能直接更改模型吗?
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
}
}