aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/qml/qqmlopenmetaobject.cpp4
-rw-r--r--src/qml/qml/qqmlopenmetaobject_p.h2
-rw-r--r--src/qml/util/qqmlpropertymap.cpp40
-rw-r--r--src/qml/util/qqmlpropertymap.h11
-rw-r--r--tests/auto/qml/qqmlpropertymap/tst_qqmlpropertymap.cpp43
5 files changed, 92 insertions, 8 deletions
diff --git a/src/qml/qml/qqmlopenmetaobject.cpp b/src/qml/qml/qqmlopenmetaobject.cpp
index 4774f7e126..bd40cc3993 100644
--- a/src/qml/qml/qqmlopenmetaobject.cpp
+++ b/src/qml/qml/qqmlopenmetaobject.cpp
@@ -175,13 +175,13 @@ public:
bool cacheProperties;
};
-QQmlOpenMetaObject::QQmlOpenMetaObject(QObject *obj, bool automatic)
+QQmlOpenMetaObject::QQmlOpenMetaObject(QObject *obj, const QMetaObject *base, bool automatic)
: d(new QQmlOpenMetaObjectPrivate(this))
{
d->autoCreate = automatic;
d->object = obj;
- d->type = new QQmlOpenMetaObjectType(obj->metaObject(), 0);
+ d->type = new QQmlOpenMetaObjectType(base ? base : obj->metaObject(), 0);
d->type->d->referers.insert(this);
QObjectPrivate *op = QObjectPrivate::get(obj);
diff --git a/src/qml/qml/qqmlopenmetaobject_p.h b/src/qml/qml/qqmlopenmetaobject_p.h
index a45d7d8259..bfd96f7cd7 100644
--- a/src/qml/qml/qqmlopenmetaobject_p.h
+++ b/src/qml/qml/qqmlopenmetaobject_p.h
@@ -83,7 +83,7 @@ class QQmlOpenMetaObjectPrivate;
class Q_QML_PRIVATE_EXPORT QQmlOpenMetaObject : public QAbstractDynamicMetaObject
{
public:
- QQmlOpenMetaObject(QObject *, bool = true);
+ QQmlOpenMetaObject(QObject *, const QMetaObject * = 0, bool = true);
QQmlOpenMetaObject(QObject *, QQmlOpenMetaObjectType *, bool = true);
~QQmlOpenMetaObject();
diff --git a/src/qml/util/qqmlpropertymap.cpp b/src/qml/util/qqmlpropertymap.cpp
index cdc82fe86e..37f9e3118a 100644
--- a/src/qml/util/qqmlpropertymap.cpp
+++ b/src/qml/util/qqmlpropertymap.cpp
@@ -53,7 +53,7 @@ QT_BEGIN_NAMESPACE
class QQmlPropertyMapMetaObject : public QQmlOpenMetaObject
{
public:
- QQmlPropertyMapMetaObject(QQmlPropertyMap *obj, QQmlPropertyMapPrivate *objPriv);
+ QQmlPropertyMapMetaObject(QQmlPropertyMap *obj, QQmlPropertyMapPrivate *objPriv, const QMetaObject *staticMetaObject);
protected:
virtual QVariant propertyWriteValue(int, const QVariant &);
@@ -110,7 +110,8 @@ const QString &QQmlPropertyMapPrivate::propertyName(int index) const
return keys[index];
}
-QQmlPropertyMapMetaObject::QQmlPropertyMapMetaObject(QQmlPropertyMap *obj, QQmlPropertyMapPrivate *objPriv) : QQmlOpenMetaObject(obj)
+QQmlPropertyMapMetaObject::QQmlPropertyMapMetaObject(QQmlPropertyMap *obj, QQmlPropertyMapPrivate *objPriv, const QMetaObject *staticMetaObject)
+ : QQmlOpenMetaObject(obj, staticMetaObject)
{
map = obj;
priv = objPriv;
@@ -176,16 +177,20 @@ int QQmlPropertyMapMetaObject::createProperty(const char *name, const char *valu
\note It is not possible to remove keys from the map; once a key has been added, you can only
modify or clear its associated value.
+
+ \note When deriving a class from QQmlPropertyMap, use the
+ \l {QQmlPropertyMap::QQmlPropertyMap(DerivedType *derived, QObject *parent)}
+ {protected two-argument constructor}
+ which ensures that the class is correctly registered with the Qt \l {Meta-Object System}.
*/
/*!
Constructs a bindable map with parent object \a parent.
*/
QQmlPropertyMap::QQmlPropertyMap(QObject *parent)
-: QObject(*(new QQmlPropertyMapPrivate), parent)
+: QObject(*allocatePrivate(), parent)
{
- Q_D(QQmlPropertyMap);
- d->mo = new QQmlPropertyMapMetaObject(this, d);
+ init(metaObject());
}
/*!
@@ -331,9 +336,23 @@ QVariant QQmlPropertyMap::operator[](const QString &key) const
*/
QVariant QQmlPropertyMap::updateValue(const QString &key, const QVariant &input)
{
+ Q_UNUSED(key)
return input;
}
+/*! \internal */
+void QQmlPropertyMap::init(const QMetaObject *staticMetaObject)
+{
+ Q_D(QQmlPropertyMap);
+ d->mo = new QQmlPropertyMapMetaObject(this, d, staticMetaObject);
+}
+
+/*! \internal */
+QObjectPrivate *QQmlPropertyMap::allocatePrivate()
+{
+ return new QQmlPropertyMapPrivate;
+}
+
/*!
\fn void QQmlPropertyMap::valueChanged(const QString &key, const QVariant &value)
This signal is emitted whenever one of the values in the map is changed. \a key
@@ -343,4 +362,15 @@ QVariant QQmlPropertyMap::updateValue(const QString &key, const QVariant &input)
or clear() - it is only emitted when a value is updated from QML.
*/
+/*!
+ \fn QQmlPropertyMap::QQmlPropertyMap(DerivedType *derived, QObject *parent)
+
+ Constructs a bindable map with parent object \a parent. Use this constructor
+ in classes derived from QQmlPropertyMap.
+
+ The type of \a derived is used to register the property map with the \l {Meta-Object System},
+ which is necessary to ensure that properties of the derived class are accessible.
+ This type must be derived from QQmlPropertyMap.
+*/
+
QT_END_NAMESPACE
diff --git a/src/qml/util/qqmlpropertymap.h b/src/qml/util/qqmlpropertymap.h
index bfd11e5c80..f7d69be7fb 100644
--- a/src/qml/util/qqmlpropertymap.h
+++ b/src/qml/util/qqmlpropertymap.h
@@ -82,7 +82,18 @@ Q_SIGNALS:
protected:
virtual QVariant updateValue(const QString &key, const QVariant &input);
+ template<class DerivedType>
+ QQmlPropertyMap(DerivedType *derived, QObject *parent = 0)
+ : QObject(*allocatePrivate(), parent)
+ {
+ Q_UNUSED(derived)
+ init(&DerivedType::staticMetaObject);
+ }
+
private:
+ void init(const QMetaObject *staticMetaObject);
+ static QObjectPrivate *allocatePrivate();
+
Q_DECLARE_PRIVATE(QQmlPropertyMap)
Q_DISABLE_COPY(QQmlPropertyMap)
};
diff --git a/tests/auto/qml/qqmlpropertymap/tst_qqmlpropertymap.cpp b/tests/auto/qml/qqmlpropertymap/tst_qqmlpropertymap.cpp
index 4e39ad3a41..3fd9dbec8f 100644
--- a/tests/auto/qml/qqmlpropertymap/tst_qqmlpropertymap.cpp
+++ b/tests/auto/qml/qqmlpropertymap/tst_qqmlpropertymap.cpp
@@ -64,6 +64,7 @@ private slots:
void crashBug();
void QTBUG_17868();
+ void metaObjectAccessibility();
};
void tst_QQmlPropertyMap::insert()
@@ -280,6 +281,48 @@ void tst_QQmlPropertyMap::QTBUG_17868()
}
+class MyEnhancedPropertyMap : public QQmlPropertyMap
+{
+ Q_OBJECT
+public:
+ MyEnhancedPropertyMap() : QQmlPropertyMap(this) {}
+
+signals:
+ void testSignal();
+
+public slots:
+ void testSlot() {}
+};
+
+namespace
+{
+ QStringList messages;
+ void msgHandler(QtMsgType, const char *msg)
+ {
+ messages << QLatin1String(msg);
+ }
+}
+
+void tst_QQmlPropertyMap::metaObjectAccessibility()
+{
+ messages.clear();
+ QtMsgHandler old = qInstallMsgHandler(msgHandler);
+
+ QQmlEngine engine;
+
+ MyEnhancedPropertyMap map;
+
+ // Verify that signals and slots of QQmlPropertyMap-derived classes are accessible
+ QObject::connect(&map, SIGNAL(testSignal()), &engine, SIGNAL(quit()));
+ QObject::connect(&engine, SIGNAL(quit()), &map, SLOT(testSlot()));
+
+ QCOMPARE(map.metaObject()->className(), "MyEnhancedPropertyMap");
+
+ qInstallMsgHandler(old);
+
+ QCOMPARE(messages.count(), 0);
+}
+
QTEST_MAIN(tst_QQmlPropertyMap)
#include "tst_qqmlpropertymap.moc"