[英]QML | Persistent Memory in ListModel (storing ListModel for later use)
Given a ListModel with multiple layers of stored information (arrays of elements stored within elements), is there a way to store the model and recall it later?给定一个具有多层存储信息(存储在元素中的元素数组)的 ListModel,有没有办法存储模型并在以后调用它?
I've tried storing ListModel as a JSON string, but it doesn't keep track of child objects.我尝试将 ListModel 存储为 JSON 字符串,但它不跟踪子对象。 For example, in the following snippet, the output tells me there is a "kids" object, but has no knowledge of "kid1" nor "kid2".
例如,在下面的代码片段中,输出告诉我有一个“kids”对象,但不知道“kid1”和“kid2”。 Same goes for the "store" object, but no knowledge of "duck1" nor "duck2".
“商店”对象也是如此,但不知道“duck1”或“duck2”。
import QtQuick 2.9
import QtQuick.Window 2.2
Window {
visible: true
width: 640
height: 480
ListModel {
id: listModel
ListElement {
name: "Parent"
kids: [
ListElement {kid: "kid1"},
ListElement {kid: "kid2"}
]
}
ListElement {
name: "store"
ducks: [
ListElement {duck: "duck1"},
ListElement {duck: "duck2"}
]
}
Component.onCompleted: {
var datamodel = []
for (var i = 0; i < this.count; ++i)
datamodel.push(this.get(i))
console.log(JSON.stringify(datamodel))
}
}
}
Here is the output, which fails to show any information about the child objects.这是输出,它无法显示有关子对象的任何信息。 I would expect there to be "kid1" and "kid2" under the "Parent" object.
我希望“父”对象下有“kid1”和“kid2”。
[
{
"kids": {
"objectName": "",
"count": 2,
"dynamicRoles": false
},
"name": "Parent"
},
{
"name": "store",
"ducks": {
"objectName": "",
"count": 2,
"dynamicRoles": false
}
}
]
Edit: I would expect the output to be more like this:编辑:我希望输出更像这样:
[
{
"name": "Parent",
"kids": [
{
"kid": "kid1"
},
{
"kid": "kid2"
}
]
},
{
"name": "store",
"ducks": [
{
"duck": "duck1"
},
{
"duck": "duck2"
}
]
}
]
It seems you want to save the current state of your model when application is closed and restore it when application is started again.似乎您想在应用程序关闭时保存模型的当前状态,并在应用程序再次启动时恢复它。 Definitely ability to serialize and deserialize model is a must here.
在这里,序列化和反序列化模型的能力绝对是必须的。
JSON.parse
to recreate objects from their string version.JSON.parse
从其字符串版本重新创建对象。Time permitting, another solution would be to design the model on C++ side and expose it as is or as QVariant to Qml code.如果时间允许,另一种解决方案是在 C++ 端设计模型并将其按原样或作为 QVariant 公开给 Qml 代码。 Then (de)serialization will be entrusted to C++ code.
然后(反)序列化将委托给 C++ 代码。 The pros are: code is cleaner and I/O operations are faster.
优点是:代码更简洁,I/O 操作更快。 Cons are: it needs more time to be implemented and would be unnecessarily complicated in my opinion if the overall application is not feature-demanding.
缺点是:它需要更多的时间来实现,如果整个应用程序对功能要求不高,我认为会不必要地复杂化。
With the help of misterFad's link, I created a serialize() function that is specific to my application.在 misterFad 的链接的帮助下,我创建了一个特定于我的应用程序的 serialize() 函数。 Posting the code to spark intuition in others potentially stuck on the problem.
发布代码以激发其他人的直觉可能会卡在问题上。
import QtQuick 2.9
import QtQuick.Window 2.2
Window {
visible: true
width: 640
height: 480
function serialize(object) {
var model = object
var totalText = "["
for(var i = 0; i < model.count; i++) {
var element = model.get(i)
totalText += "{\"name\": \"" + element.name + "\""
if(element.kids.count) totalText += ",\"kids\": " + serialize(element.kids)
totalText += "}" + (i < model.count-1 ? ",": "")
}
return totalText + "]"
}
ListModel {
id: listModel
ListElement {
name: "dad"
kids: [
ListElement {
name: "kid1";
kids: []
},
ListElement {
name: "kid2";
kids: [
ListElement {name: "grandkid1"; kids: []},
ListElement {name: "grandkid2"; kids: []}
]
}
]
}
ListElement {
name: "store"
kids: [
ListElement {name: "duck1"; kids: []},
ListElement {name: "duck2"; kids: []}
]
}
Component.onCompleted: console.log(serialize(listModel))
}
}
output JSON is:输出 JSON 是:
[
{
"name": "dad",
"kids": [
{
"name": "kid1"
},
{
"name": "kid2",
"kids": [
{
"name": "grandkid1"
},
{
"name": "grandkid2"
}
]
}
]
},
{
"name": "store",
"kids": [
{
"name": "duck1"
},
{
"name": "duck2"
}
]
}
]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.