From 62c2061a501563e7f2929c5883f01955af0f2fc1 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Thu, 16 Aug 2012 02:19:56 +0200 Subject: Add automatic metatype registration for Q_PROPERTY types. In Qt 4, the user needs to call qRegisterMetaType if the property could otherwise be read before the type is registered with the metatype system. This patch makes that unnecessary and automatic by registering it when the first read indicates that it is not yet registered instead or when QMetaProperty::userType is called before it is registered. The types which are automatically registered exclude the built-in types, which do not need to be registered, and include metatypes which are automatically declared, such as pointers to QObject derived types and containers of existing metatypes. Change-Id: I0a06d8efdcb64121618e2378366d0142fa0771f5 Reviewed-by: Kent Hansen --- tests/auto/tools/moc/tst_moc.cpp | 172 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) (limited to 'tests/auto/tools/moc') diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp index f60ab112ed..c6178c7c2e 100644 --- a/tests/auto/tools/moc/tst_moc.cpp +++ b/tests/auto/tools/moc/tst_moc.cpp @@ -549,6 +549,7 @@ private slots: void finalClasses(); void explicitOverrideControl_data(); void explicitOverrideControl(); + void autoPropertyMetaTypeRegistration(); signals: void sigWithUnsignedArg(unsigned foo); @@ -2293,6 +2294,177 @@ void tst_Moc::explicitOverrideControl() #endif } +class CustomQObject : public QObject +{ + Q_OBJECT + Q_ENUMS(Number) +public: + enum Number { + Zero, + One, + Two + }; + explicit CustomQObject(QObject *parent = 0) + : QObject(parent) + { + } +}; + +Q_DECLARE_METATYPE(CustomQObject::Number) + +typedef CustomQObject* CustomQObjectStar; +Q_DECLARE_METATYPE(CustomQObjectStar); + +namespace SomeNamespace { + +class NamespacedQObject : public QObject +{ + Q_OBJECT +public: + explicit NamespacedQObject(QObject *parent = 0) + : QObject(parent) + { + + } +}; + +struct NamespacedNonQObject {}; +} +Q_DECLARE_METATYPE(SomeNamespace::NamespacedNonQObject) + +class AutoRegistrationObject : public QObject +{ + Q_OBJECT + Q_PROPERTY(QObject* object READ object CONSTANT) + Q_PROPERTY(CustomQObject* customObject READ customObject CONSTANT) + Q_PROPERTY(QSharedPointer customObjectP READ customObjectP CONSTANT) + Q_PROPERTY(QWeakPointer customObjectWP READ customObjectWP CONSTANT) + Q_PROPERTY(QPointer customObjectTP READ customObjectTP CONSTANT) + Q_PROPERTY(QList listInt READ listInt CONSTANT) + Q_PROPERTY(QVector vectorVariant READ vectorVariant CONSTANT) + Q_PROPERTY(QList listObject READ listObject CONSTANT) + Q_PROPERTY(QVector> vectorListInt READ vectorListInt CONSTANT) + Q_PROPERTY(QVector> vectorListObject READ vectorListObject CONSTANT) + Q_PROPERTY(CustomQObject::Number enumValue READ enumValue CONSTANT) + Q_PROPERTY(CustomQObjectStar customObjectTypedef READ customObjectTypedef CONSTANT) + Q_PROPERTY(SomeNamespace::NamespacedQObject* customObjectNamespaced READ customObjectNamespaced CONSTANT) + Q_PROPERTY(SomeNamespace::NamespacedNonQObject customNonQObjectNamespaced READ customNonQObjectNamespaced CONSTANT) +public: + AutoRegistrationObject(QObject *parent = 0) + : QObject(parent) + { + } + + QObject* object() const + { + return 0; + } + + QSharedPointer customObjectP() const + { + return QSharedPointer(); + } + + QWeakPointer customObjectWP() const + { + return QWeakPointer(); + } + + QPointer customObjectTP() const + { + return QPointer(); + } + + CustomQObject* customObject() const + { + return 0; + } + + QList listInt() const + { + return QList(); + } + + QVector vectorVariant() const + { + return QVector(); + } + + QList listObject() const + { + return QList(); + } + + QVector > vectorListInt() const + { + return QVector >(); + } + + QVector > vectorListObject() const + { + return QVector >(); + } + + CustomQObject::Number enumValue() const + { + return CustomQObject::Zero; + } + + CustomQObjectStar customObjectTypedef() const + { + return 0; + } + + SomeNamespace::NamespacedQObject* customObjectNamespaced() const + { + return 0; + } + + SomeNamespace::NamespacedNonQObject customNonQObjectNamespaced() const + { + return SomeNamespace::NamespacedNonQObject(); + } +}; + +void tst_Moc::autoPropertyMetaTypeRegistration() +{ + AutoRegistrationObject aro; + + static const int numPropertiesUnderTest = 15; + QVector propertyMetaTypeIds; + propertyMetaTypeIds.reserve(numPropertiesUnderTest); + + const QMetaObject *metaObject = aro.metaObject(); + QCOMPARE(metaObject->propertyCount(), numPropertiesUnderTest); + for (int i = 0; i < metaObject->propertyCount(); ++i) { + const QMetaProperty prop = metaObject->property(i); + propertyMetaTypeIds.append(prop.userType()); + QVariant var = prop.read(&aro); + QVERIFY(var.isValid()); + } + + // Verify that QMetaProperty::userType gave us what we expected. + QVector expectedMetaTypeIds = QVector() + << QMetaType::QString // QObject::userType + << QMetaType::QObjectStar // AutoRegistrationObject::object + << qMetaTypeId() // etc. + << qMetaTypeId >() + << qMetaTypeId >() + << qMetaTypeId >() + << qMetaTypeId >() + << qMetaTypeId >() + << qMetaTypeId >() + << qMetaTypeId > >() + << qMetaTypeId > >() + << qMetaTypeId() + << qMetaTypeId() + << qMetaTypeId() + << qMetaTypeId() + ; + + QCOMPARE(propertyMetaTypeIds, expectedMetaTypeIds); +} + QTEST_MAIN(tst_Moc) #include "tst_moc.moc" -- cgit v1.2.3