diff options
Diffstat (limited to 'src/qml')
-rw-r--r-- | src/qml/doc/src/qmlfunctions.qdoc | 24 | ||||
-rw-r--r-- | src/qml/qml/qqmlmetatype.cpp | 12 | ||||
-rw-r--r-- | src/qml/qml/qqmltypewrapper.cpp | 13 |
3 files changed, 20 insertions, 29 deletions
diff --git a/src/qml/doc/src/qmlfunctions.qdoc b/src/qml/doc/src/qmlfunctions.qdoc index 55ca040af6..6445a003a1 100644 --- a/src/qml/doc/src/qmlfunctions.qdoc +++ b/src/qml/doc/src/qmlfunctions.qdoc @@ -538,30 +538,6 @@ } \endqml - Since singleton types do not have an associated QQmlContext object, then within the functions of a QObject-derived - type that is registered as a singleton type implementation the QML context and engine information is not available. - The QQmlEngine::contextForObject() function returns NULL when supplied with a pointer to an QObject that - implements a singleton type. - - Extending the above example: - - \code - class SingletonTypeExample : public QObject - { - ... - - Q_INVOKABLE void doSomethingElse() - { - // QML Engine/Context information is not accessible here: - Q_ASSERT(QQmlEngine::contextForObject(this) == 0); - Q_ASSERT(qmlContext(this) == 0); - Q_ASSERT(qmlEngine(this) == 0); - } - - ... - } - \endcode - \sa {Choosing the Correct Integration Method Between C++ and QML} */ diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index 0429df6185..307f9a9ec6 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -264,7 +264,14 @@ void QQmlMetaTypeData::registerType(QQmlTypePrivate *priv) void QQmlType::SingletonInstanceInfo::init(QQmlEngine *e) { if (scriptCallback && scriptApi(e).isUndefined()) { - setScriptApi(e, scriptCallback(e, e)); + QJSValue value = scriptCallback(e, e); + if (value.isQObject()) { + QObject *o = value.toQObject(); + // even though the object is defined in C++, qmlContext(obj) and qmlEngine(obj) + // should behave identically to QML singleton types. + e->setContextForObject(o, new QQmlContext(e->rootContext(), e)); + } + setScriptApi(e, value); } else if (qobjectCallback && !qobjectApi(e)) { QObject *o = qobjectCallback(e, e); setQObjectApi(e, o); @@ -273,6 +280,9 @@ void QQmlType::SingletonInstanceInfo::init(QQmlEngine *e) } // if this object can use a property cache, create it now QQmlData::ensurePropertyCache(e, o); + // even though the object is defined in C++, qmlContext(obj) and qmlEngine(obj) + // should behave identically to QML singleton types. + e->setContextForObject(o, new QQmlContext(e->rootContext(), e)); } else if (!url.isEmpty() && !qobjectApi(e)) { QQmlComponent component(e, url, QQmlComponent::PreferSynchronous); QObject *o = component.beginCreate(e->rootContext()); diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp index 26f035705c..7270cffb00 100644 --- a/src/qml/qml/qqmltypewrapper.cpp +++ b/src/qml/qml/qqmltypewrapper.cpp @@ -95,12 +95,17 @@ QObject* QQmlTypeWrapper::singletonObject() const QVariant QQmlTypeWrapper::toVariant() const { - QObject *qobjectSingleton = singletonObject(); - if (qobjectSingleton) + // Only Singleton type wrappers can be converted to a variant. + if (!isSingleton()) + return QVariant(); + + QQmlEngine *e = engine()->qmlEngine(); + QQmlType::SingletonInstanceInfo *siinfo = d()->type().singletonInstanceInfo(); + siinfo->init(e); + if (QObject *qobjectSingleton = siinfo->qobjectApi(e)) return QVariant::fromValue<QObject*>(qobjectSingleton); - // only QObject Singleton Type can be converted to a variant. - return QVariant(); + return QVariant::fromValue<QJSValue>(siinfo->scriptApi(e)); } |