【问题标题】:Is there a way to type an object parsed from json in qml有没有办法在 qml 中键入从 json 解析的对象
【发布时间】:2021-08-16 16:48:22
【问题描述】:

json文件是这样的。我想在 qml 中为它定义一个类,就像 typescript 中的 interface 关键字一样。

{
    "ScannerID": "ID",
    "Status": 1,
    "SuccessRate": 0.999,
    "Result": [{
            "Codes": "result_11111",
            "Positions": {
                "CenterX": 10.0,
                "CenterY": 10.0,
                "Width": 100.0,
                "Height": 100.0,
                "Angle": 50
            },
            "Types": "QrCode"
        },
        //more items
    ]
}

我试图在文件ScannerResult.qml中定义一个qml类

import QtQuick 2.4

QtObject {
    property string pScannerID
    property int pStatus
    property real pSuccessRate
    // how to define Result with strong type?
    property ? pResult

    function load(obj) {
        pScannerID = obj.ScannerID
        //......
    }
}

那就用吧

...
ScannerResult {
    id: scannerResult
}

function log(jsonstr) {
    let obj = JSON.parse(jsonstr);
    scannerResult.load(obj)
    console.log(scannerResult.pScannerID) // it works
}
...

但是"Result"键下的对象向量很难处理。因为 qml 不允许在 A 类下定义 B 类。
那么有没有人知道如何定义一个强类型类来保存从 json 中解析的对象在 qml 中?然后我可以在 qtcreator 中使用具有自动完成功能的类。

【问题讨论】:

  • “但是'Result'键下的对象向量很难处理。”有什么难的?你的问题到底是什么?
  • @JarMan 这很难,因为 qml 不允许在 A 类下定义 B 类,而我通常在 C++ 中这样做。我的问题是如何定义一个强类型类来保存 qml 中从 json 解析的对象。
  • "qml 不允许在 A 类下定义 B 类"——我不确定这意味着什么。 inline components 会帮助你吗?或者您可以在 A 类之外定义 B 类吗?
  • @JarMan 内联组件似乎无法容纳长度未知的向量。外部定义会使项目过于复杂。不过谢谢你的回复。

标签: qt qml


【解决方案1】:

您可以创建一个property var 并将其分配为一个列表/数组/向量来保存pResult。要填充此列表,您可以创建“B 类”Component,并在解析 JSON 对象时动态创建此类的实例。

使用您的代码结构,这里是ScannerResult.qml 的更新版本:

import QtQuick 2.4

QtObject {
    property string pScannerID
    property int pStatus
    property real pSuccessRate
    property var pResult: []

    function load(obj) {
        pScannerID = obj.ScannerID
        //... etc
        for (var element of obj.Result) {
            let resultQtObject = resultComponent.createObject(this, {})
            resultQtObject.pCodes = element.Codes
            resultQtObject.pTypes = element.Types
            resultQtObject.pPositions.pCenterX = element.Positions.CenterX
            //... etc
            pResult.push(resultQtObject)
        }
    }

    property Component resultComponent: Component {

        QtObject {
            property string pCodes
            property string pTypes
            property QtObject pPositions: QtObject {
                property real pCenterX
                property real pCenterY
                property real pWidth
                property real pHeight
                property int pAngle
            }
        }
    }
}

您更新后的log 函数的工作原理如下:

    function log(jsonstr) {
        let obj = JSON.parse(jsonstr);
        scannerResult.load(obj)
        console.log(scannerResult.pScannerID) // it works
        console.log(scannerResult.pResult[0].pPositions.pCenterX) // it works
    }

因为您是在运行时动态创建此Component 的实例,QtCreator 无法为其提供自动完成建议。正如您提到的,您的向量长度未知,我相信运行时实例化是您唯一的选择,因此没有可以适应自动完成的解决方案。

另外需要注意的是,如果您多次重新运行log()/load(),您将需要清理pResult 列表和destroy() 动态创建的对象。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多