Solved QJsonObject: Insert in a deep field
-
I would like to insert/append a
QJsonObject
inside a deepQJsonObject/Array
field.
Example:QJsonObject root; QJsonArray my_array; QJsonObject first; first.insert("first", 1); my_array.append(first); root.insert("my_array", my_array);
Until here...all ok.
Now, I would like to append a second
QJsonObject
inside themy_array
field.
Like:QJsonObject second; second.insert("second", 2); root["my_array"].append(second); // Not working!
Why? How can I fix it?
-
@fem_dev Hi,
The issue here is that the compiler cannot know you are accessing a QJSonArray.
QJsonValueRef QJsonObject::operator[](QStringView key)
returns a QJsonValue, and not a QJsonArray, you can access the array usingQJsonValue::toArray() const
but then it returns a const array so you cannot modify it "on the fly"If you have still access to your array instance:
my_array.append(first); ... my_array.append(second); root.insert("my_array", my_array);
But if you don't, you need to get the array, append your data, and then put it back in the QJsonObject.
QJsonArray myArray = root["my_array"].toArray(); myArray.append(second); root["my_array"] = myArray;
-
@fem_dev Hi,
The issue here is that the compiler cannot know you are accessing a QJSonArray.
QJsonValueRef QJsonObject::operator[](QStringView key)
returns a QJsonValue, and not a QJsonArray, you can access the array usingQJsonValue::toArray() const
but then it returns a const array so you cannot modify it "on the fly"If you have still access to your array instance:
my_array.append(first); ... my_array.append(second); root.insert("my_array", my_array);
But if you don't, you need to get the array, append your data, and then put it back in the QJsonObject.
QJsonArray myArray = root["my_array"].toArray(); myArray.append(second); root["my_array"] = myArray;
-
@Gojir4 thank you!
If I use this:
QJsonArray myArray = root["my_array"].toArray(); // Object copying? myArray.append(second); root["my_array"] = myArray;
Question1:
It is copying the array? Or just the pointer value?
Is there a way to avoid object copying?Question 2:
Ok, I understood that I need thetoArray()
method.
But now, why I can't do that?root["my_array"].toArray().append(second); // Not working too
-
Hi
try
root["my_array"] = root["my_array"].toArray().append(second);I think
root["my_array"].toArray() is a copy and not a reference/pointer so you are modifying a temp object and not the
original one. -
@mrjj I tried:
root["my_array"] = root["my_array"].toArray().append(second);
But I got this compilation time error:
app.cpp:392:26: error: no viable overloaded '=' qjsonvalue.h:181:20: note: candidate function not viable: cannot convert argument of incomplete type 'void' to 'const QJsonValue' for 1st argument qjsonvalue.h:182:20: note: candidate function not viable: cannot convert argument of incomplete type 'void' to 'const QJsonValueRef' for 1st argument
Question:
Is there another way toappend()
avoiding the object copying below? Using a pointer or a reference?QJsonArray myArray = root["my_array"].toArray(); // Object copying? myArray.append(second); root["my_array"] = myArray;
-
@fem_dev said in QJsonObject: Insert in a deep field:
QJsonValueRef
Ok it complains about incomplete type
so i wonder if it misses an include?Anyway, @Gojir4 showed the working way.
- Is there another way to append() avoiding the object copying below? Using a pointer or a reference?
Well it seems its a copy
https://doc.qt.io/qt-5/qjsonvalue.html#toArray
So unless it can return a ref than i think not.
- Is there another way to append() avoiding the object copying below? Using a pointer or a reference?
-
It seems like the JSON objects in Qt are designed to be assembled rather than modified:
https://doc.qt.io/qt-5/qtcore-serialization-savegame-example.htmlIs there a word for this type of code design?
-
@fcarney
Well its a value-orientated design utilizing the implicit sharing Qt provides making the copying cheap.
However, it does allow ref for some of the constructs via QJsonValueRefIm not sure it has a concrete name other than maybe
Surprising :)