简体   繁体   English

QML | ListModel 中的 Persistent Memory(存储 ListModel 以备后用)

[英]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.在这里,序列化和反序列化模型的能力绝对是必须的。

[1/2] Qml-only based implementation [1/2] 基于 Qml 的实现

  1. Use this serializer from this SO answer, assuming you don't mind binding to third-party licenses (this one is totally free and the code seems reliable but I haven't tried or tested it).使用这种从串行SO答案,假设你不介意结合第三方许可证(这个人是完全免费的代码似乎可靠的,但我还没有尝试过或测试过)。 Then use JSON.parse to recreate objects from their string version.然后使用JSON.parse从其字符串版本重新创建对象。
  2. Craft your own (de)serializer and make sure it's tightly closed to the actual model you're working with.制作您自己的(反)序列化程序,并确保它与您正在使用的实际模型紧密相连。 For instance in case not all of the properties from an object in your model need to be backuped/restored, then it might be wiser to directly look for the properties you need and only play with them.例如,如果不是模型中某个对象的所有属性都需要备份/恢复,那么直接查找您需要的属性并仅使用它们可能更明智。 This might considerably lower the overhead cost of searching through hierarchy of properties but you'll endup with a very specific (de)serializer which is not reusable across projects.这可能会大大降低搜索属性层次结构的开销成本,但您最终会得到一个非常具体的(反)序列化器,它不能跨项目重用。

[2/2] Qml/C++ implementation [2/2] Qml/C++实现

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM