diff options
-rw-r--r-- | .qmake.conf | 2 | ||||
-rw-r--r-- | examples/webchannel/shared/qwebchannel.js | 12 | ||||
-rw-r--r-- | src/webchannel/qmetaobjectpublisher.cpp | 12 | ||||
-rw-r--r-- | src/webchannel/qmetaobjectpublisher_p.h | 8 | ||||
-rw-r--r-- | tests/auto/qml/testobject.cpp | 9 | ||||
-rw-r--r-- | tests/auto/qml/testobject.h | 7 | ||||
-rw-r--r-- | tests/auto/qml/tst_webchannel.qml | 3 |
7 files changed, 49 insertions, 4 deletions
diff --git a/.qmake.conf b/.qmake.conf index 7b49e2c..879fb0f 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -1,4 +1,4 @@ load(qt_build_config) CONFIG += warning_clean -MODULE_VERSION = 5.13.0 +MODULE_VERSION = 5.14.0 diff --git a/examples/webchannel/shared/qwebchannel.js b/examples/webchannel/shared/qwebchannel.js index 5b047c2..d75e148 100644 --- a/examples/webchannel/shared/qwebchannel.js +++ b/examples/webchannel/shared/qwebchannel.js @@ -197,10 +197,16 @@ function QObject(name, data, webChannel) } return ret; } - if (!response - || !response["__QObject*__"] - || response.id === undefined) { + if (!(response instanceof Object)) return response; + + if (!response["__QObject*__"] + || response.id === undefined) { + var jObj = {}; + for (var propName in response) { + jObj[propName] = object.unwrapQObject(response[propName]); + } + return jObj; } var objectId = response.id; diff --git a/src/webchannel/qmetaobjectpublisher.cpp b/src/webchannel/qmetaobjectpublisher.cpp index c9285b7..3c96126 100644 --- a/src/webchannel/qmetaobjectpublisher.cpp +++ b/src/webchannel/qmetaobjectpublisher.cpp @@ -620,6 +620,9 @@ QJsonValue QMetaObjectPublisher::wrapResult(const QVariant &result, QWebChannelA } else if (result.canConvert<QVariantList>()) { // recurse and potentially wrap contents of the array return wrapList(result.toList(), transport); + } else if (result.canConvert<QVariantMap>()) { + // recurse and potentially wrap contents of the map + return wrapMap(result.toMap(), transport); } return QJsonValue::fromVariant(result); @@ -634,6 +637,15 @@ QJsonArray QMetaObjectPublisher::wrapList(const QVariantList &list, QWebChannelA return array; } +QJsonObject QMetaObjectPublisher::wrapMap(const QVariantMap &map, QWebChannelAbstractTransport *transport, const QString &parentObjectId) +{ + QJsonObject obj; + for (QVariantMap::const_iterator i = map.begin(); i != map.end(); i++) { + obj.insert(i.key(), wrapResult(i.value(), transport, parentObjectId)); + } + return obj; +} + void QMetaObjectPublisher::deleteWrappedObject(QObject *object) const { if (!wrappedObjects.contains(registeredObjectIds.value(object))) { diff --git a/src/webchannel/qmetaobjectpublisher_p.h b/src/webchannel/qmetaobjectpublisher_p.h index d02a933..1535a70 100644 --- a/src/webchannel/qmetaobjectpublisher_p.h +++ b/src/webchannel/qmetaobjectpublisher_p.h @@ -199,6 +199,14 @@ public: const QString &parentObjectId = QString()); /** + * Convert a variant map for consumption by the client. + * + * This properly handles QML values and also wraps the result if required. + */ + QJsonObject wrapMap(const QVariantMap &map, QWebChannelAbstractTransport *transport, + const QString &parentObjectId = QString()); + + /** * Invoke delete later on @p object. */ void deleteWrappedObject(QObject *object) const; diff --git a/tests/auto/qml/testobject.cpp b/tests/auto/qml/testobject.cpp index 2be7773..4968bf4 100644 --- a/tests/auto/qml/testobject.cpp +++ b/tests/auto/qml/testobject.cpp @@ -33,13 +33,22 @@ QT_BEGIN_NAMESPACE TestObject::TestObject(QObject* parent) : QObject(parent) + , embeddedObject(new QObject(this)) { + embeddedObject->setObjectName("embedded"); } TestObject::~TestObject() { } +QVariantMap TestObject::objectMap() const +{ + QVariantMap map; + map.insert("subObject", QVariant::fromValue(embeddedObject)); + return map; +} + void TestObject::triggerSignals() { emit testSignalBool(true); diff --git a/tests/auto/qml/testobject.h b/tests/auto/qml/testobject.h index e025ea6..5813dae 100644 --- a/tests/auto/qml/testobject.h +++ b/tests/auto/qml/testobject.h @@ -31,22 +31,29 @@ #define TESTOBJECT_H #include <QObject> +#include <QVariantMap> QT_BEGIN_NAMESPACE class TestObject : public QObject { Q_OBJECT + Q_PROPERTY(QVariantMap objectMap READ objectMap CONSTANT) public: explicit TestObject(QObject *parent = Q_NULLPTR); ~TestObject(); + QVariantMap objectMap() const; + public slots: void triggerSignals(); signals: void testSignalBool(bool testBool); void testSignalInt(int testInt); + +private: + QObject *embeddedObject; }; QT_END_NAMESPACE diff --git a/tests/auto/qml/tst_webchannel.qml b/tests/auto/qml/tst_webchannel.qml index 6da6c4b..298376f 100644 --- a/tests/auto/qml/tst_webchannel.qml +++ b/tests/auto/qml/tst_webchannel.qml @@ -297,6 +297,9 @@ TestCase { compare(channel.objects.myFactory.objects.length, 2); compare(channel.objects.myFactory.objects[0].objectName, "bar"); compare(channel.objects.myFactory.objects[1].objectName, "baz"); + // map property as well + compare(channel.objects.testObject.objectMap.subObject.objectName, + "embedded"); // also works with properties that reference other registered objects compare(channel.objects.myFactory.otherObject, channel.objects.myObj); |