diff options
author | Nils Jeisecke <nils.jeisecke@saltation.com> | 2018-03-02 16:57:11 +0100 |
---|---|---|
committer | Nils Jeisecke <nils.jeisecke@saltation.com> | 2018-03-10 06:12:24 +0000 |
commit | fee8944cbe2a976e1b4a71c5df048e84a0bc6db0 (patch) | |
tree | 210fe33464d31b577f92a078faa2fed738540788 /tests/auto | |
parent | b767c7363f7ceda88553fb8abb6d4cb70b70bd2f (diff) |
Allow use of template class instances inheriting from a Q_GADGET in Qml
The Q_GADGET macro cannot be used in templates. It can however be useful
to derive a template class from a Q_GADGET enabled base class to benefit
from type safety features in C++ (e.g. the class could represent an id
or handle for some C++ type).
For proper wrapping of a QVariant with a gadget value in a QJSValue, the
QMetaType::IsGadget flag must be set for the registered template
instance type - which does not happen prior to the fix because
IsGadgetHelper requires qt_check_for_QGADGET_macro to be defined in the
registered class but not in an ancestor class - in other words: The
class must declare Q_GADGET.
To overcome this, IsGadgetHelper/IsPointerToGadgetHelper can now
differentiate between a Q_GADGET flagged class (allowing
automatic registration) and a derived class, e.g. a template class
(forcing Q_DECLARE_METATYPE to be used explicitly).
[ChangeLog][QtCore][QMetaObject] It is now possible to use template
class instances inheriting from a Q_GADGET in Qml
Task-number: QTBUG-66744
Change-Id: I7632ad45cff79fa422b3f852ca0b963f35fab155
Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
Diffstat (limited to 'tests/auto')
-rw-r--r-- | tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index cc628ee26e..c6fd5d17c2 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -141,6 +141,14 @@ public: class CustomNonQObject {}; class GadgetDerived : public CustomGadget {}; +// cannot use Q_GADGET due to moc limitations but wants to behave like +// a Q_GADGET in Qml land +template<typename T> +class GadgetDerivedAndTyped : public CustomGadget {}; + +Q_DECLARE_METATYPE(GadgetDerivedAndTyped<int>) +Q_DECLARE_METATYPE(GadgetDerivedAndTyped<int>*) + void tst_QMetaType::defined() { QCOMPARE(int(QMetaTypeId2<QString>::Defined), 1); @@ -157,6 +165,10 @@ void tst_QMetaType::defined() QVERIFY(!QMetaTypeId2<CustomNonQObject>::Defined); QVERIFY(!QMetaTypeId2<CustomNonQObject*>::Defined); QVERIFY(!QMetaTypeId2<CustomGadget_NonDefaultConstructible>::Defined); + + // registered with Q_DECLARE_METATYPE + QVERIFY(QMetaTypeId2<GadgetDerivedAndTyped<int>>::Defined); + QVERIFY(QMetaTypeId2<GadgetDerivedAndTyped<int>*>::Defined); } struct Bar @@ -396,6 +408,10 @@ void tst_QMetaType::typeName_data() QTest::newRow("CustomGadget*") << ::qMetaTypeId<CustomGadget*>() << QString::fromLatin1("CustomGadget*"); QTest::newRow("CustomQObject::CustomQEnum") << ::qMetaTypeId<CustomQObject::CustomQEnum>() << QString::fromLatin1("CustomQObject::CustomQEnum"); QTest::newRow("Qt::ArrowType") << ::qMetaTypeId<Qt::ArrowType>() << QString::fromLatin1("Qt::ArrowType"); + + // template instance class derived from Q_GADGET enabled class + QTest::newRow("GadgetDerivedAndTyped<int>") << ::qMetaTypeId<GadgetDerivedAndTyped<int>>() << QString::fromLatin1("GadgetDerivedAndTyped<int>"); + QTest::newRow("GadgetDerivedAndTyped<int>*") << ::qMetaTypeId<GadgetDerivedAndTyped<int>*>() << QString::fromLatin1("GadgetDerivedAndTyped<int>*"); } void tst_QMetaType::typeName() @@ -1703,6 +1719,9 @@ void tst_QMetaType::metaObject_data() QTest::newRow("MyGadget*") << ::qMetaTypeId<MyGadget*>() << &MyGadget::staticMetaObject << false << true << false; QTest::newRow("MyEnum") << ::qMetaTypeId<MyGadget::MyEnum>() << &MyGadget::staticMetaObject << false << false << false; QTest::newRow("Qt::ScrollBarPolicy") << ::qMetaTypeId<Qt::ScrollBarPolicy>() << &QObject::staticQtMetaObject << false << false << false; + + QTest::newRow("GadgetDerivedAndTyped<int>") << ::qMetaTypeId<GadgetDerivedAndTyped<int>>() << &GadgetDerivedAndTyped<int>::staticMetaObject << true << false << false; + QTest::newRow("GadgetDerivedAndTyped<int>*") << ::qMetaTypeId<GadgetDerivedAndTyped<int>*>() << &GadgetDerivedAndTyped<int>::staticMetaObject << false << true << false; } |