aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2021-01-05 17:52:00 +0100
committerUlf Hermann <ulf.hermann@qt.io>2021-01-12 20:58:14 +0100
commite35b82922398e09779a162592cdedd50677e63cf (patch)
tree0f28e7e8bbf011c16399c9b84917dc5dda70f88f /src/qml
parente3cca3df718d8ff298d2d73ce4d6139a3ba620f9 (diff)
QQmlListReference: Allow construction from a QVariant
Currently there is no public API to transform a QVariant holding a QQmlListProperty into a QQmlListReference. We cannot pass QQmlListProperty itself as that is templated. The metatype-based casting is somewhat evil, but not more so than what we already have in the other ctor. Change-Id: I2d56499b1fd188613bc71016cb00ec23081d3cea Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/qml/qqmllist.cpp36
-rw-r--r--src/qml/qml/qqmllist.h1
2 files changed, 37 insertions, 0 deletions
diff --git a/src/qml/qml/qqmllist.cpp b/src/qml/qml/qqmllist.cpp
index cffdf7c907..fe0b820a1e 100644
--- a/src/qml/qml/qqmllist.cpp
+++ b/src/qml/qml/qqmllist.cpp
@@ -120,6 +120,42 @@ QQmlListReference::QQmlListReference()
}
/*!
+\since 6.1
+
+Constructs a QQmlListReference from a QVariant \a variant containing a QQmlListProperty. If
+\a variant does not contain a list property, an invalid QQmlListReference is created. If the object
+owning the list property is destroyed after the reference is constructed, it will automatically
+become invalid. That is, it is safe to hold QQmlListReference instances even after the object is
+deleted.
+
+The \a engine is required to look up the element type, which may be a dynamically created QML type.
+If it's omitted, only pre-registered types are available.
+*/
+QQmlListReference::QQmlListReference(const QVariant &variant, QQmlEngine *engine)
+ : d(nullptr)
+{
+ const QMetaType t = variant.metaType();
+ if (!(t.flags() & QMetaType::IsQmlList))
+ return;
+
+ QQmlEnginePrivate *p = engine ? QQmlEnginePrivate::get(engine) : nullptr;
+ const int listType = p ? p->listType(t.id()) : QQmlMetaType::listType(t.id());
+ if (listType == -1)
+ return;
+
+ d = new QQmlListReferencePrivate;
+ d->propertyType = t.id();
+ d->elementType = p
+ ? p->rawMetaObjectForType(listType)
+ : QQmlMetaType::qmlType(listType).baseMetaObject();
+
+ d->property.~QQmlListProperty();
+ t.construct(&d->property, variant.constData());
+
+ d->object = d->property.object;
+}
+
+/*!
Constructs a QQmlListReference for \a object's \a property. If \a property is not a list
property, an invalid QQmlListReference is created. If \a object is destroyed after
the reference is constructed, it will automatically become invalid. That is, it is safe to hold
diff --git a/src/qml/qml/qqmllist.h b/src/qml/qml/qqmllist.h
index 3cc353ef30..abf4ec6ebf 100644
--- a/src/qml/qml/qqmllist.h
+++ b/src/qml/qml/qqmllist.h
@@ -197,6 +197,7 @@ class Q_QML_EXPORT QQmlListReference
{
public:
QQmlListReference();
+ explicit QQmlListReference(const QVariant &variant, QQmlEngine *engine = nullptr);
QQmlListReference(QObject *, const char *property, QQmlEngine * = nullptr);
QQmlListReference(const QQmlListReference &);
QQmlListReference &operator=(const QQmlListReference &);