Details
-
Suggestion
-
Resolution: Done
-
P3: Somewhat important
-
5.0.0 RC 1
-
None
Description
From discussion here: http://qt-project.org/forums/viewthread/22500/
Currently, QML lacks a consistent API for managing Javascript "var" data in C++. There are two solutions, both with their own problems:
1. expose a QVariant in C++, e.g. Q_PROPERTY(QVariant blah READ blah WRITE setBlah NOTIFY blahChanged)
This works perfectly for exposing read-only data to QML, but does not implement write-back semantics – modifying an exposed QVariant in QML has no effect, not even a warning message. For example, assuming blah() returns a QVariant containing a QVariantList containing a QVariantMap, the following code has no effect:
function modifyBlah() { blah[0].foo = 3; }
2. expose a QJSValue in C++, e.g. Q_PROPERTY(QJSValue blah READ blah WRITE setBlah NOTIFY blahChanged)
QJSValue implements write-back semantics, so data can be modified in both QML and C++. However, the QJSValue API is incomplete – it cannot create new arrays, objects, or wrapped QObject pointers. Instead, one must first get a QQmlContext pointer by calling QQmlEngine::contextForObject(this), then call
context->engine()->newObject
(or newArray, or newQObject) to create a new QJSValue, then finally assign it to a property, e.g.
m_blah->setProperty("foo", myNewJSValue)
I have to say that using QJSValue types feels very rough. Two ways come to mind that would make them much more intuitive:
1. if QJSValues had a pointer to their engine, setProperty could be overridden to handle QObject*, and creating arrays/objects could also be handled directly from the QJSValue.
2. an alternate approach could be to wrap it using something similar to QQmlProperty (QQmlJSValueProperty?) that has convenience methods for creating QObject QJSValues, new Arrays and new Objects.
There are zero examples exposing QJSValue properties. I only found out that they were supported when I googled them out of curiosity and came across a JIRA bug that indicated they were now supported by QML.
I must also say that it was very surprising that QVariant did not support write-back semantics. At the very least, this should be documented.