Reputation: 23
The json document is like this. I want to define a class for it in qml, just like the interface
keyword in typescript does.
{
"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
]
}
I tried to define a qml class in file ScannerResult.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
//......
}
}
then use it
...
ScannerResult {
id: scannerResult
}
function log(jsonstr) {
let obj = JSON.parse(jsonstr);
scannerResult.load(obj)
console.log(scannerResult.pScannerID) // it works
}
...
But it's hard to handle the vector of objects under "Result"
key. Because qml doesn't allow to define class B under class A.
So does anyone have a good idea about how to define a strong-typed class to hold the object parsed from json in qml? Then I can use that class with auto-completion in qtcreator.
Upvotes: 2
Views: 2073
Reputation: 1738
You can create a property var
and assign it as a list/array/vector to hold pResult
. To populate this list, you can create a "class B" Component
, and dynamically create instances of this class them when parsing your JSON object.
Using your code structure, here is an updated version of 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
}
}
}
}
Your updated log
function works as follows:
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
}
Because you are dynamically creating instances of this Component
at runtime, QtCreator cannot make auto-completion suggestions for it. As you mentioned your vector is unknown length, I believe that runtime instantiation is your only option, and thus there is no solution that can accommodate auto-completion.
One other thing to note is that if you are re-running log()
/load()
many times you will need to clean the pResult
list and destroy()
the dynamically created objects.
Upvotes: 1