diff options
author | Kari Oikarinen <kari.oikarinen@qt.io> | 2019-08-27 07:50:48 +0300 |
---|---|---|
committer | Kari Oikarinen <kari.oikarinen@qt.io> | 2019-08-27 07:50:48 +0300 |
commit | 3fbaa2618c0c43a4dd6550666a789327f0d8f2cc (patch) | |
tree | dc48f088144a44e2026f196ad14add4519d4d30a /src/qml | |
parent | 7919751e999d68d4b4e9dae37493d607e7759105 (diff) | |
parent | 50ccfaa7ad26e0872ac50b92b346bebbd3002838 (diff) |
Merge dev into 5.14
Change-Id: I3ae119563f41fda63ac2b452f2d05fa83e411faa
Diffstat (limited to 'src/qml')
-rw-r--r-- | src/qml/doc/src/qmlfunctions.qdoc | 10 | ||||
-rw-r--r-- | src/qml/qml/qqml.h | 10 | ||||
-rw-r--r-- | src/qml/qml/qqmlapplicationengine.cpp | 18 | ||||
-rw-r--r-- | src/qml/qml/qqmlapplicationengine.h | 1 | ||||
-rw-r--r-- | src/qml/qml/qqmlapplicationengine_p.h | 1 | ||||
-rw-r--r-- | src/qml/qml/qqmlcomponent.cpp | 74 | ||||
-rw-r--r-- | src/qml/qml/qqmlcomponent.h | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlcomponent_p.h | 3 | ||||
-rw-r--r-- | src/qml/qml/qqmlengine.cpp | 8 | ||||
-rw-r--r-- | src/qml/qml/qqmlloggingcategory_p.h | 2 | ||||
-rw-r--r-- | src/qml/types/qqmlconnections.cpp | 2 | ||||
-rw-r--r-- | src/qml/types/qqmlconnections_p.h | 4 |
12 files changed, 116 insertions, 19 deletions
diff --git a/src/qml/doc/src/qmlfunctions.qdoc b/src/qml/doc/src/qmlfunctions.qdoc index 9c106558fd..c71d18418a 100644 --- a/src/qml/doc/src/qmlfunctions.qdoc +++ b/src/qml/doc/src/qmlfunctions.qdoc @@ -274,6 +274,16 @@ */ /*! + \fn int qmlRegisterAnonymousType(const char *uri, int versionMajor) + + This template function registers the C++ type in the QML system. Instances of this type cannot be created from the QML system. + + Use this function when the type will not be referenced by name. Use \a uri and \a versionMajor to indicate to which module the type belongs. + + \sa {Choosing the Correct Integration Method Between C++ and QML} +*/ + +/*! \fn int qmlRegisterType() \relates QQmlEngine \overload diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h index bfd1c88b28..a93b012c70 100644 --- a/src/qml/qml/qqml.h +++ b/src/qml/qml/qqml.h @@ -102,7 +102,7 @@ class QQmlPropertyValueInterceptor; void Q_QML_EXPORT qmlClearTypeRegistrations(); template<typename T> -int qmlRegisterType() +int qmlRegisterAnonymousType(const char *uri, int versionMajor=1) { QML_GETTYPENAMES @@ -115,7 +115,7 @@ int qmlRegisterType() nullptr, QString(), - nullptr, 0, 0, nullptr, &T::staticMetaObject, + uri, versionMajor, 0, nullptr, &T::staticMetaObject, QQmlPrivate::attachedPropertiesFunc<T>(), QQmlPrivate::attachedPropertiesMetaObject<T>(), @@ -133,6 +133,12 @@ int qmlRegisterType() return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); } +template<typename T> +QT_DEPRECATED_VERSION_X_5_14("Use qmlRegisterAnonymousType instead") int qmlRegisterType() +{ + return qmlRegisterAnonymousType<T>(""); +} + int Q_QML_EXPORT qmlRegisterTypeNotAvailable(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& message); template<typename T> diff --git a/src/qml/qml/qqmlapplicationengine.cpp b/src/qml/qml/qqmlapplicationengine.cpp index e93cfcadb9..d04a89b514 100644 --- a/src/qml/qml/qqmlapplicationengine.cpp +++ b/src/qml/qml/qqmlapplicationengine.cpp @@ -131,7 +131,7 @@ void QQmlApplicationEnginePrivate::finishLoad(QQmlComponent *c) q->objectCreated(nullptr, c->url()); break; case QQmlComponent::Ready: { - auto newObj = c->create(); + auto newObj = initialProperties.empty() ? c->create() : c->createWithInitialProperties(initialProperties); objects << newObj; QObject::connect(newObj, &QObject::destroyed, q, [&](QObject *obj) { objects.removeAll(obj); }); q->objectCreated(objects.constLast(), c->url()); @@ -279,6 +279,22 @@ void QQmlApplicationEngine::load(const QString &filePath) } /*! + Sets the initial properties with which the QML component gets initialized after + it gets loaded. + + + \sa QQmlComponent::setInitialProperties + \sa QQmlApplicationEngine::load + \sa QQmlApplicationEngine::loadData + \since 5.14 +*/ +void QQmlApplicationEngine::setInitialProperties(const QVariantMap &initialProperties) +{ + Q_D(QQmlApplicationEngine); + d->initialProperties = initialProperties; +} + +/*! Loads the QML given in \a data. The object tree defined by \a data is instantiated immediately. diff --git a/src/qml/qml/qqmlapplicationengine.h b/src/qml/qml/qqmlapplicationengine.h index bb5d6b5d68..2b4de91154 100644 --- a/src/qml/qml/qqmlapplicationengine.h +++ b/src/qml/qml/qqmlapplicationengine.h @@ -66,6 +66,7 @@ public: public Q_SLOTS: void load(const QUrl &url); void load(const QString &filePath); + void setInitialProperties(const QVariantMap &initialProperties); void loadData(const QByteArray &data, const QUrl &url = QUrl()); Q_SIGNALS: diff --git a/src/qml/qml/qqmlapplicationengine_p.h b/src/qml/qml/qqmlapplicationengine_p.h index 7a341847bd..1279e400e8 100644 --- a/src/qml/qml/qqmlapplicationengine_p.h +++ b/src/qml/qml/qqmlapplicationengine_p.h @@ -73,6 +73,7 @@ public: void loadTranslations(const QUrl &rootFile); void finishLoad(QQmlComponent *component); QList<QObject *> objects; + QVariantMap initialProperties; }; QT_END_NAMESPACE diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp index fefe2bc685..ed8c41a582 100644 --- a/src/qml/qml/qqmlcomponent.cpp +++ b/src/qml/qml/qqmlcomponent.cpp @@ -350,6 +350,32 @@ void QQmlComponentPrivate::clear() compilationUnit = nullptr; } +QObject *QQmlComponentPrivate::doBeginCreate(QQmlComponent *q, QQmlContext *context) +{ + if (!engine) { + // ###Qt6: In Qt 6, it should be impossible for users to create a QQmlComponent without an engine, and we can remove this check + qWarning("QQmlComponent: Must provide an engine before calling create"); + return nullptr; + } + if (!context) + context = engine->rootContext(); + return q->beginCreate(context); +} + +bool QQmlComponentPrivate::setInitialProperty(QObject *component, const QString& name, const QVariant &value) +{ + QQmlProperty prop(component, name); + auto privProp = QQmlPropertyPrivate::get(prop); + if (!prop.isValid() || !privProp->writeValueProperty(value, nullptr)) { + QQmlError error{}; + error.setUrl(url); + error.setDescription(QLatin1String("Could not set property %1").arg(name)); + state.errors.push_back(error); + return false; + } else + return true; +} + /*! \internal */ @@ -780,18 +806,28 @@ QObject *QQmlComponent::create(QQmlContext *context) { Q_D(QQmlComponent); - if (!d->engine) { - // ###Qt6: In Qt 6, it should be impossible for users to create a QQmlComponent without an engine, and we can remove this check - qWarning("QQmlComponent: Must provide an engine before calling create"); - return nullptr; - } + QObject *rv = d->doBeginCreate(this, context); + if (rv) + completeCreate(); + return rv; +} - if (!context) - context = d->engine->rootContext(); +/*! + Create an object instance of this component, and initialize its toplevel properties according to initalPropertyValues. - QObject *rv = beginCreate(context); - if (rv) + + \sa QQmlComponent::create + \since 5.14 +*/ +QObject *QQmlComponent::createWithInitialProperties(const QVariantMap& initialProperties, QQmlContext *context) +{ + Q_D(QQmlComponent); + + QObject *rv = d->doBeginCreate(this, context); + if (rv) { + setInitialProperties(rv, initialProperties); completeCreate(); + } return rv; } @@ -1067,6 +1103,26 @@ void QQmlComponent::create(QQmlIncubator &incubator, QQmlContext *context, enginePriv->incubate(incubator, forContextData); } +/*! + Set toplevel properties of the component. + + + This method provides advanced control over component instance creation. + In general, programmers should use + \l QQmlComponent::createWithInitialProperties to create a component. + + Use this method after beginCreate and before completeCreate has been called. + If a provided property does not exist, a warning is issued. + + \since 5.14 +*/ +void QQmlComponent::setInitialProperties(QObject *component, const QVariantMap &properties) +{ + Q_D(QQmlComponent); + for (auto it = properties.constBegin(); it != properties.constEnd(); ++it) + d->setInitialProperty(component, it.key(), it.value()); +} + /* This is essentially a copy of QQmlComponent::create(); except it takes the QQmlContextData arguments instead of QQmlContext which means we don't have to construct the rather weighty diff --git a/src/qml/qml/qqmlcomponent.h b/src/qml/qml/qqmlcomponent.h index 39b6d4526f..f259c99b08 100644 --- a/src/qml/qml/qqmlcomponent.h +++ b/src/qml/qml/qqmlcomponent.h @@ -100,6 +100,8 @@ public: QUrl url() const; virtual QObject *create(QQmlContext *context = nullptr); + QObject *createWithInitialProperties(const QVariantMap& initialProperties, QQmlContext *context = nullptr); + void setInitialProperties(QObject *component, const QVariantMap &properties); virtual QObject *beginCreate(QQmlContext *); virtual void completeCreate(); diff --git a/src/qml/qml/qqmlcomponent_p.h b/src/qml/qml/qqmlcomponent_p.h index 9a967501c9..2170646b89 100644 --- a/src/qml/qml/qqmlcomponent_p.h +++ b/src/qml/qml/qqmlcomponent_p.h @@ -143,6 +143,9 @@ public: static QQmlComponentPrivate *get(QQmlComponent *c) { return static_cast<QQmlComponentPrivate *>(QObjectPrivate::get(c)); } + + QObject *doBeginCreate(QQmlComponent *q, QQmlContext *context); + bool setInitialProperty(QObject *component, const QString &name, const QVariant& value); }; QT_END_NAMESPACE diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 9c3c9de81e..0fd07ea209 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -210,14 +210,14 @@ void QQmlEnginePrivate::defineModule() // TODO: We won't need Connections to be a custom type anymore once we can drop the // automatic signal handler inference from undeclared properties. qmlRegisterCustomType<QQmlConnections>(uri, 2, 0, "Connections", new QQmlConnectionsParser); - qmlRegisterCustomType<QQmlConnections, 1>(uri, 2, 3, "Connections", new QQmlConnectionsParser); // Only available in QtQml >= 2.3 + qmlRegisterCustomType<QQmlConnections, 3>(uri, 2, 3, "Connections", new QQmlConnectionsParser); // Only available in QtQml >= 2.3 #if QT_CONFIG(qml_animation) qmlRegisterType<QQmlTimer>(uri, 2, 0, "Timer"); #endif qmlRegisterType<QQmlLoggingCategory>(uri, 2, 8, "LoggingCategory"); // Only available in >= 2.8 - qmlRegisterType<QQmlLoggingCategory, 1>(uri, 2, 12, "LoggingCategory"); // Only available in >= 2.12 + qmlRegisterType<QQmlLoggingCategory, 12>(uri, 2, 12, "LoggingCategory"); // Only available in >= 2.12 #if QT_CONFIG(qml_locale) qmlRegisterUncreatableType<QQmlLocale>(uri, 2, 2, "Locale", QQmlEngine::tr("Locale cannot be instantiated. Use Qt.locale()")); @@ -236,12 +236,12 @@ void QQmlEnginePrivate::registerQuickTypes() qmlRegisterType<QQmlBind>(uri, 2, 0, "Binding"); qmlRegisterType<QQmlBind, 8>(uri, 2, 8, "Binding"); qmlRegisterCustomType<QQmlConnections>(uri, 2, 0, "Connections", new QQmlConnectionsParser); - qmlRegisterCustomType<QQmlConnections, 1>(uri, 2, 7, "Connections", new QQmlConnectionsParser); + qmlRegisterCustomType<QQmlConnections, 3>(uri, 2, 7, "Connections", new QQmlConnectionsParser); #if QT_CONFIG(qml_animation) qmlRegisterType<QQmlTimer>(uri, 2, 0,"Timer"); #endif qmlRegisterType<QQmlLoggingCategory>(uri, 2, 8, "LoggingCategory"); - qmlRegisterType<QQmlLoggingCategory, 1>(uri, 2, 12, "LoggingCategory"); + qmlRegisterType<QQmlLoggingCategory, 12>(uri, 2, 12, "LoggingCategory"); #if QT_CONFIG(qml_locale) qmlRegisterUncreatableType<QQmlLocale>(uri, 2, 0, "Locale", QQmlEngine::tr("Locale cannot be instantiated. Use Qt.locale()")); #endif diff --git a/src/qml/qml/qqmlloggingcategory_p.h b/src/qml/qml/qqmlloggingcategory_p.h index ece06e04b4..ee5d9af2e7 100644 --- a/src/qml/qml/qqmlloggingcategory_p.h +++ b/src/qml/qml/qqmlloggingcategory_p.h @@ -65,7 +65,7 @@ class QQmlLoggingCategory : public QObject, public QQmlParserStatus Q_INTERFACES(QQmlParserStatus) Q_PROPERTY(QString name READ name WRITE setName) - Q_PROPERTY(DefaultLogLevel defaultLogLevel READ defaultLogLevel WRITE setDefaultLogLevel REVISION 1) + Q_PROPERTY(DefaultLogLevel defaultLogLevel READ defaultLogLevel WRITE setDefaultLogLevel REVISION 12) public: enum DefaultLogLevel { diff --git a/src/qml/types/qqmlconnections.cpp b/src/qml/types/qqmlconnections.cpp index f9188b1bb5..1e801641e5 100644 --- a/src/qml/types/qqmlconnections.cpp +++ b/src/qml/types/qqmlconnections.cpp @@ -274,8 +274,10 @@ void QQmlConnections::connectSignals() if (d->bindings.isEmpty()) { connectSignalsToMethods(); } else { +#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) qmlWarning(this) << tr("Implicitly defined onFoo properties in Connections are deprecated. " "Use this syntax instead: function onFoo(<arguments>) { ... }"); +#endif connectSignalsToBindings(); } } diff --git a/src/qml/types/qqmlconnections_p.h b/src/qml/types/qqmlconnections_p.h index 1acc86239f..5d28e8e8be 100644 --- a/src/qml/types/qqmlconnections_p.h +++ b/src/qml/types/qqmlconnections_p.h @@ -69,7 +69,7 @@ class Q_AUTOTEST_EXPORT QQmlConnections : public QObject, public QQmlParserStatu Q_INTERFACES(QQmlParserStatus) Q_PROPERTY(QObject *target READ target WRITE setTarget NOTIFY targetChanged) - Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged REVISION 1) + Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged REVISION 3) Q_PROPERTY(bool ignoreUnknownSignals READ ignoreUnknownSignals WRITE setIgnoreUnknownSignals) public: @@ -87,7 +87,7 @@ public: Q_SIGNALS: void targetChanged(); - Q_REVISION(1) void enabledChanged(); + Q_REVISION(3) void enabledChanged(); private: void connectSignals(); |