QMLからC++のinvokeメソッドの引数にJSONオブジェクトの変数を入れて、
C++側で取り出そうとしたときにハマったのでメモ。
#QMLファイルでJSONオブジェクトを用意する。
main.qml
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Component.onCompleted: {
// こんな感じのJSONオブジェクトを用意する。
var Obj = {
name: "taro",
x: 10,
y: 20,
size: {
width: 100,
height: 200
}
}
// C++のメソッドを呼ぶ。
JsonObject.notify(Obj);
}
}
#JSONオブジェクトから値を取り出す。
値の取り出し方はQVariantをQJSValueに変換して、propertyというメソッドを使ったあとにさらに任意の型に変換をする。
jsonobject.cpp
void JsonObject::notify(QVariant data)
{
qDebug() << data;
QJSValue value = data.value<QJSValue>();
qDebug() << value.property("x").toInt();
qDebug() << value.property("size").property("width").toInt();
}
すると下記のログが出力される。
QML debugging is enabled. Only use this in a safe environment.
QVariant(QJSValue, )
10
100
他の方法
QJSValue型に変換したあと、再度QVariant型に変換する。
jsonobject.cpp
void JsonObject::notify(QVariant data)
{
qDebug() << data << "\n";
QJSValue value = data.value<QJSValue>();
qDebug() << value.toVariant();
}
すると下記のログが出力される。
QVariantの中にQMapが格納されていることがわかる。
QVariant(QJSValue, )
QVariant(QVariantMap, QMap(("name", QVariant(QString, "taro"))("size", QVariant(QVariantMap, QMap(("height", QVariant(int, 200))("width", QVariant(int, 100)))))("x", QVariant(int, 10))("y", QVariant(double, 20.1))))
さらに、QMap型→QJsonObject型→QJsonDocument型→QString型→wchar_t型へと順次変換する。
jsonobject.cpp
wchar_t* JsonObject::convert(QMap<QString, QVariant> map)
{
QJsonObject json;
QMapIterator<QString, QVariant> i(map);
// QJsonObject型に変換
while (i.hasNext())
{
i.next();
json.insert(i.key(), i.value().toJsonValue());
}
// QJsonDocument型に変換
QJsonDocument doc(json);
// QString型に変換
QString strJson(doc.toJson(QJsonDocument::Compact));
// wchar_t型に変換
wchar_t *array = new wchar_t[strJson.length() + 1];
strJson.toWCharArray(array);
return array;
}