问题
I have a QVariantMap created in C++ from a JSON object and I want to update this object from QML. I set it as a context property.
// main.cpp
engine.rootContext()->setContextProperty("myjson", myqvariantmap);
In QML I tried updating its properties but it seems to be read-only. The docs support this, saying
Mind that QVariantList and QVariantMap properties of C++ types are stored as values and cannot be changed in place by QML code. You can only replace the whole map or list, but not manipulate its contents.
Is there a workaround or an alternative type I can use in place of QVariatnMap?
回答1:
One possible option is QQmlPropertyMap:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlPropertyMap>
#include <QQmlContext>
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlPropertyMap qpropertymap;
qpropertymap.insert("name", "foo");
QObject::connect(&qpropertymap, &QQmlPropertyMap::valueChanged, [](const QString &key, const QVariant &value){
qDebug() << key << value;
});
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("qpropertymap", &qpropertymap);
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
return app.exec();
}
import QtQuick 2.12
import QtQuick.Window 2.12
Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")
Component.onCompleted: {
qpropertymap.name = "bar"
// or
// qpropertymap["name"] = "bar"
}
}
回答2:
Here is a snippet to go with @eyllanesc's solution to convert from QVariantMap to QQmlPropertyMap.
void toPropertyMap(const QVariantMap& source, QQmlPropertyMap* dest) {
for (const auto& key : source.keys()) {
(*dest)[key] = source[key];
}
}
来源:https://stackoverflow.com/questions/64879496/editing-a-qvariantmap-from-qml