Bring qmetaobjectbuilder in sync with moc
qmetaobjectbuilder should generate meta-objects of the same version as moc; in the future, when the moc version is bumped, QMOB has to be adapted at the same time. QMOB was generating version 4 meta-objects. This patch makes it generate version 6 (the current version). This also fixes a bug with using qt_static_metacall with QMOB (setStaticMetacallFunction()); it was already using the version 6 qt_static_metacall signature, which isn't compatible with version 4. Also add tests that ensure that the QMOB-generated meta-object works with real objects; in particular we want to test the codepaths in Qt that check for version >= 4. Change-Id: I64a151ea5c947a6f8b7a00e85a39866446c735e9 Reviewed-by: Bradley T. Hughes <bradley.hughes@nokia.com>
This commit is contained in:
parent
8bbb00e44e
commit
b184dd0a01
@ -109,6 +109,8 @@ class QMutex;
|
|||||||
|
|
||||||
struct QMetaObjectPrivate
|
struct QMetaObjectPrivate
|
||||||
{
|
{
|
||||||
|
enum { OutputRevision = 6 }; // Used by moc and qmetaobjectbuilder
|
||||||
|
|
||||||
int revision;
|
int revision;
|
||||||
int className;
|
int className;
|
||||||
int classInfoCount, classInfoData;
|
int classInfoCount, classInfoData;
|
||||||
|
@ -1136,7 +1136,8 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (buf) {
|
if (buf) {
|
||||||
pmeta->revision = 4;
|
Q_STATIC_ASSERT_X(QMetaObjectPrivate::OutputRevision == 6, "QMetaObjectBuilder should generate the same version as moc");
|
||||||
|
pmeta->revision = QMetaObjectPrivate::OutputRevision;
|
||||||
pmeta->flags = d->flags;
|
pmeta->flags = d->flags;
|
||||||
pmeta->className = 0; // Class name is always the first string.
|
pmeta->className = 0; // Class name is always the first string.
|
||||||
//pmeta->signalCount is handled in the "output method loop" as an optimization.
|
//pmeta->signalCount is handled in the "output method loop" as an optimization.
|
||||||
|
@ -162,7 +162,7 @@ void Generator::generateCode()
|
|||||||
int index = 14;
|
int index = 14;
|
||||||
fprintf(out, "static const uint qt_meta_data_%s[] = {\n", qualifiedClassNameIdentifier.constData());
|
fprintf(out, "static const uint qt_meta_data_%s[] = {\n", qualifiedClassNameIdentifier.constData());
|
||||||
fprintf(out, "\n // content:\n");
|
fprintf(out, "\n // content:\n");
|
||||||
fprintf(out, " %4d, // revision\n", 6);
|
fprintf(out, " %4d, // revision\n", int(QMetaObjectPrivate::OutputRevision));
|
||||||
fprintf(out, " %4d, // classname\n", strreg(cdef->qualified));
|
fprintf(out, " %4d, // classname\n", strreg(cdef->qualified));
|
||||||
fprintf(out, " %4d, %4d, // classinfo\n", cdef->classInfoList.count(), cdef->classInfoList.count() ? index : 0);
|
fprintf(out, " %4d, %4d, // classinfo\n", cdef->classInfoList.count(), cdef->classInfoList.count() ? index : 0);
|
||||||
index += cdef->classInfoList.count() * 2;
|
index += cdef->classInfoList.count() * 2;
|
||||||
|
@ -47,7 +47,6 @@ class tst_QMetaObjectBuilder : public QObject
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private slots:
|
private slots:
|
||||||
void mocVersionCheck();
|
|
||||||
void create();
|
void create();
|
||||||
void className();
|
void className();
|
||||||
void superClass();
|
void superClass();
|
||||||
@ -67,6 +66,14 @@ private slots:
|
|||||||
void serialize();
|
void serialize();
|
||||||
void removeNotifySignal();
|
void removeNotifySignal();
|
||||||
|
|
||||||
|
void usage_signal();
|
||||||
|
void usage_property();
|
||||||
|
void usage_slot();
|
||||||
|
void usage_method();
|
||||||
|
void usage_constructor();
|
||||||
|
void usage_connect();
|
||||||
|
void usage_templateConnect();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool checkForSideEffects
|
static bool checkForSideEffects
|
||||||
(const QMetaObjectBuilder& builder,
|
(const QMetaObjectBuilder& builder,
|
||||||
@ -130,18 +137,6 @@ signals:
|
|||||||
void propChanged(const QString&);
|
void propChanged(const QString&);
|
||||||
};
|
};
|
||||||
|
|
||||||
void tst_QMetaObjectBuilder::mocVersionCheck()
|
|
||||||
{
|
|
||||||
// This test will fail when the moc version number is changed.
|
|
||||||
// It is intended as a reminder to also update QMetaObjectBuilder
|
|
||||||
// whenenver moc changes. Once QMetaObjectBuilder has been
|
|
||||||
// updated, this test can be changed to check for the next version.
|
|
||||||
int version = int(QObject::staticMetaObject.d.data[0]);
|
|
||||||
QVERIFY(version == 4 || version == 5 || version == 6);
|
|
||||||
version = int(staticMetaObject.d.data[0]);
|
|
||||||
QVERIFY(version == 4 || version == 5 || version == 6);
|
|
||||||
}
|
|
||||||
|
|
||||||
void tst_QMetaObjectBuilder::create()
|
void tst_QMetaObjectBuilder::create()
|
||||||
{
|
{
|
||||||
QMetaObjectBuilder builder;
|
QMetaObjectBuilder builder;
|
||||||
@ -1274,6 +1269,353 @@ bool tst_QMetaObjectBuilder::sameMetaObject
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// This class is used to test that the meta-object generated by QMOB can be
|
||||||
|
// used by a real object.
|
||||||
|
// The class manually implements the functions normally generated by moc, and
|
||||||
|
// creates the corresponding meta-object using QMOB. The autotests check that
|
||||||
|
// this object can be used by QObject/QMetaObject functionality (property
|
||||||
|
// access, signals & slots, constructing instances, ...).
|
||||||
|
|
||||||
|
class TestObject : public QObject
|
||||||
|
{
|
||||||
|
// Manually expanded from Q_OBJECT macro
|
||||||
|
public:
|
||||||
|
Q_OBJECT_CHECK
|
||||||
|
virtual const QMetaObject *metaObject() const;
|
||||||
|
virtual void *qt_metacast(const char *);
|
||||||
|
virtual int qt_metacall(QMetaObject::Call, int, void **);
|
||||||
|
private:
|
||||||
|
Q_DECL_HIDDEN static const QMetaObjectExtraData staticMetaObjectExtraData;
|
||||||
|
Q_DECL_HIDDEN static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **);
|
||||||
|
|
||||||
|
//Q_PROPERTY(int intProp READ intProp WRITE setIntProp NOTIFY intPropChanged)
|
||||||
|
public:
|
||||||
|
TestObject(QObject *parent = 0); // Q_INVOKABLE
|
||||||
|
~TestObject();
|
||||||
|
|
||||||
|
// Property accessors
|
||||||
|
int intProp() const;
|
||||||
|
void setIntProp(int v);
|
||||||
|
|
||||||
|
void emitIntPropChanged();
|
||||||
|
|
||||||
|
int voidSlotIntArgument() const;
|
||||||
|
|
||||||
|
// Q_INVOKABLE
|
||||||
|
QVariantList listInvokableQRealQString(qreal, const QString &);
|
||||||
|
|
||||||
|
//public Q_SLOTS:
|
||||||
|
void voidSlotInt(int);
|
||||||
|
|
||||||
|
//Q_SIGNALS:
|
||||||
|
void intPropChanged(int);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static QMetaObject *buildMetaObject();
|
||||||
|
|
||||||
|
QMetaObject *m_metaObject;
|
||||||
|
int m_intProp;
|
||||||
|
int m_voidSlotIntArg;
|
||||||
|
};
|
||||||
|
|
||||||
|
const QMetaObjectExtraData TestObject::staticMetaObjectExtraData = {
|
||||||
|
0, qt_static_metacall
|
||||||
|
};
|
||||||
|
|
||||||
|
TestObject::TestObject(QObject *parent)
|
||||||
|
: QObject(parent), m_metaObject(buildMetaObject()),
|
||||||
|
m_intProp(-1), m_voidSlotIntArg(-1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
TestObject::~TestObject()
|
||||||
|
{
|
||||||
|
qFree(m_metaObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
QMetaObject *TestObject::buildMetaObject()
|
||||||
|
{
|
||||||
|
QMetaObjectBuilder builder;
|
||||||
|
// NOTE: If you change the meta-object, remember to adapt qt_metacall and
|
||||||
|
// friends below accordingly.
|
||||||
|
|
||||||
|
builder.setClassName("TestObject");
|
||||||
|
|
||||||
|
builder.setStaticMetacallFunction(qt_static_metacall);
|
||||||
|
|
||||||
|
QMetaMethodBuilder intPropChanged = builder.addSignal("intPropChanged(int)");
|
||||||
|
intPropChanged.setParameterNames(QList<QByteArray>() << "newIntPropValue");
|
||||||
|
|
||||||
|
QMetaPropertyBuilder prop = builder.addProperty("intProp", "int");
|
||||||
|
prop.setNotifySignal(intPropChanged);
|
||||||
|
|
||||||
|
QMetaMethodBuilder voidSlotInt = builder.addSlot("voidSlotInt(int)");
|
||||||
|
voidSlotInt.setParameterNames(QList<QByteArray>() << "slotIntArg");
|
||||||
|
|
||||||
|
QMetaMethodBuilder listInvokableQRealQString = builder.addMethod("listInvokableQRealQString(qreal,QString)");
|
||||||
|
listInvokableQRealQString.setReturnType("QVariantList");
|
||||||
|
listInvokableQRealQString.setParameterNames(QList<QByteArray>() << "qrealArg" << "qstringArg");
|
||||||
|
|
||||||
|
builder.addConstructor("TestObject(QObject*)");
|
||||||
|
builder.addConstructor("TestObject()");
|
||||||
|
|
||||||
|
return builder.toMetaObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
int TestObject::intProp() const
|
||||||
|
{
|
||||||
|
return m_intProp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestObject::setIntProp(int value)
|
||||||
|
{
|
||||||
|
if (m_intProp != value) {
|
||||||
|
m_intProp = value;
|
||||||
|
emit intPropChanged(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestObject::emitIntPropChanged()
|
||||||
|
{
|
||||||
|
emit intPropChanged(m_intProp);
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariantList TestObject::listInvokableQRealQString(qreal r, const QString &s)
|
||||||
|
{
|
||||||
|
return QVariantList() << r << s;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestObject::voidSlotInt(int value)
|
||||||
|
{
|
||||||
|
m_voidSlotIntArg = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TestObject::voidSlotIntArgument() const
|
||||||
|
{
|
||||||
|
return m_voidSlotIntArg;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestObject::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
|
||||||
|
{
|
||||||
|
if (_c == QMetaObject::CreateInstance) {
|
||||||
|
switch (_id) {
|
||||||
|
case 0: { TestObject *_r = new TestObject((*reinterpret_cast< QObject*(*)>(_a[1])));
|
||||||
|
if (_a[0]) *reinterpret_cast<QObject**>(_a[0]) = _r; } break;
|
||||||
|
case 1: { TestObject *_r = new TestObject();
|
||||||
|
if (_a[0]) *reinterpret_cast<QObject**>(_a[0]) = _r; } break;
|
||||||
|
default: {
|
||||||
|
QMetaMethod ctor = _o->metaObject()->constructor(_id);
|
||||||
|
qFatal("You forgot to add a case for CreateInstance %s", ctor.signature());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (_c == QMetaObject::InvokeMetaMethod) {
|
||||||
|
Q_ASSERT(_o->metaObject()->cast(_o));
|
||||||
|
TestObject *_t = static_cast<TestObject *>(_o);
|
||||||
|
switch (_id) {
|
||||||
|
case 0: _t->intPropChanged((*reinterpret_cast< int(*)>(_a[1]))); break;
|
||||||
|
case 1: _t->voidSlotInt((*reinterpret_cast< int(*)>(_a[1]))); break;
|
||||||
|
case 2: *reinterpret_cast<QVariantList(*)>(_a[0]) = _t->listInvokableQRealQString(*reinterpret_cast<qreal(*)>(_a[1]), *reinterpret_cast<QString(*)>(_a[2])); break;
|
||||||
|
default: {
|
||||||
|
QMetaMethod method = _o->metaObject()->method(_o->metaObject()->methodOffset() + _id);
|
||||||
|
qFatal("You forgot to add a case for InvokeMetaMethod %s", method.signature());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (_c == QMetaObject::IndexOfMethod) {
|
||||||
|
// This code is currently unreachable because it's only used by the
|
||||||
|
// template-based versions of connect() and disconnect(), which don't
|
||||||
|
// work with dynamically generated meta-objects (see test).
|
||||||
|
int *result = reinterpret_cast<int *>(_a[0]);
|
||||||
|
void **func = reinterpret_cast<void **>(_a[1]);
|
||||||
|
{
|
||||||
|
typedef void (TestObject::*_t)(int );
|
||||||
|
if (*reinterpret_cast<_t *>(func) == static_cast<_t>(&TestObject::intPropChanged)) {
|
||||||
|
*result = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
typedef void (TestObject::*_t)(int );
|
||||||
|
if (*reinterpret_cast<_t *>(func) == static_cast<_t>(&TestObject::voidSlotInt)) {
|
||||||
|
*result = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
typedef QVariantList (TestObject::*_t)(qreal, const QString &);
|
||||||
|
if (*reinterpret_cast<_t *>(func) == static_cast<_t>(&TestObject::listInvokableQRealQString)) {
|
||||||
|
*result = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
qFatal("You forgot to add one or more IndexOfMethod cases");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const QMetaObject *TestObject::metaObject() const
|
||||||
|
{
|
||||||
|
return m_metaObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *TestObject::qt_metacast(const char *_clname)
|
||||||
|
{
|
||||||
|
if (!_clname) return 0;
|
||||||
|
if (!strcmp(_clname, "TestObject"))
|
||||||
|
return static_cast<void*>(const_cast< TestObject*>(this));
|
||||||
|
return QObject::qt_metacast(_clname);
|
||||||
|
}
|
||||||
|
|
||||||
|
int TestObject::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
|
||||||
|
{
|
||||||
|
_id = QObject::qt_metacall(_c, _id, _a);
|
||||||
|
if (_id < 0)
|
||||||
|
return _id;
|
||||||
|
int ownMethodCount = m_metaObject->methodCount() - m_metaObject->methodOffset();
|
||||||
|
int ownPropertyCount = m_metaObject->propertyCount() - m_metaObject->propertyOffset();
|
||||||
|
if (_c == QMetaObject::InvokeMetaMethod) {
|
||||||
|
if (_id < ownMethodCount)
|
||||||
|
qt_static_metacall(this, _c, _id, _a);
|
||||||
|
_id -= ownMethodCount;
|
||||||
|
}
|
||||||
|
#ifndef QT_NO_PROPERTIES
|
||||||
|
else if (_c == QMetaObject::ReadProperty) {
|
||||||
|
void *_v = _a[0];
|
||||||
|
switch (_id) {
|
||||||
|
case 0: *reinterpret_cast< int*>(_v) = intProp(); break;
|
||||||
|
default: if (_id < ownPropertyCount) {
|
||||||
|
QMetaProperty prop = m_metaObject->property(m_metaObject->propertyOffset() + _id);
|
||||||
|
qFatal("You forgot to add a case for ReadProperty %s", prop.name());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_id -= ownPropertyCount;
|
||||||
|
} else if (_c == QMetaObject::WriteProperty) {
|
||||||
|
void *_v = _a[0];
|
||||||
|
switch (_id) {
|
||||||
|
case 0: setIntProp(*reinterpret_cast< int*>(_v)); break;
|
||||||
|
default: if (_id < ownPropertyCount) {
|
||||||
|
QMetaProperty prop = m_metaObject->property(m_metaObject->propertyOffset() + _id);
|
||||||
|
qFatal("You forgot to add a case for WriteProperty %s", prop.name());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_id -= ownPropertyCount;
|
||||||
|
} else if (_c == QMetaObject::ResetProperty) {
|
||||||
|
_id -= ownPropertyCount;
|
||||||
|
} else if (_c == QMetaObject::QueryPropertyDesignable) {
|
||||||
|
_id -= ownPropertyCount;
|
||||||
|
} else if (_c == QMetaObject::QueryPropertyScriptable) {
|
||||||
|
_id -= ownPropertyCount;
|
||||||
|
} else if (_c == QMetaObject::QueryPropertyStored) {
|
||||||
|
_id -= ownPropertyCount;
|
||||||
|
} else if (_c == QMetaObject::QueryPropertyEditable) {
|
||||||
|
_id -= ownPropertyCount;
|
||||||
|
} else if (_c == QMetaObject::QueryPropertyUser) {
|
||||||
|
_id -= ownPropertyCount;
|
||||||
|
}
|
||||||
|
#endif // QT_NO_PROPERTIES
|
||||||
|
return _id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SIGNAL 0
|
||||||
|
void TestObject::intPropChanged(int _t1)
|
||||||
|
{
|
||||||
|
void *_a[] = { 0, const_cast<void*>(reinterpret_cast<const void*>(&_t1)) };
|
||||||
|
QMetaObject::activate(this, m_metaObject, 0, _a);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void tst_QMetaObjectBuilder::usage_signal()
|
||||||
|
{
|
||||||
|
QScopedPointer<TestObject> testObject(new TestObject);
|
||||||
|
|
||||||
|
QSignalSpy propChangedSpy(testObject.data(), SIGNAL(intPropChanged(int)));
|
||||||
|
testObject->emitIntPropChanged();
|
||||||
|
QCOMPARE(propChangedSpy.count(), 1);
|
||||||
|
QCOMPARE(propChangedSpy.at(0).count(), 1);
|
||||||
|
QCOMPARE(propChangedSpy.at(0).at(0).toInt(), testObject->intProp());
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QMetaObjectBuilder::usage_property()
|
||||||
|
{
|
||||||
|
QScopedPointer<TestObject> testObject(new TestObject);
|
||||||
|
|
||||||
|
QVariant prop = testObject->property("intProp");
|
||||||
|
QCOMPARE(prop.type(), QVariant::Int);
|
||||||
|
QCOMPARE(prop.toInt(), testObject->intProp());
|
||||||
|
|
||||||
|
QSignalSpy propChangedSpy(testObject.data(), SIGNAL(intPropChanged(int)));
|
||||||
|
QVERIFY(testObject->intProp() != 123);
|
||||||
|
testObject->setProperty("intProp", 123);
|
||||||
|
QCOMPARE(propChangedSpy.count(), 1);
|
||||||
|
prop = testObject->property("intProp");
|
||||||
|
QCOMPARE(prop.type(), QVariant::Int);
|
||||||
|
QCOMPARE(prop.toInt(), 123);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QMetaObjectBuilder::usage_slot()
|
||||||
|
{
|
||||||
|
QScopedPointer<TestObject> testObject(new TestObject);
|
||||||
|
|
||||||
|
int index = testObject->metaObject()->indexOfMethod("voidSlotInt(int)");
|
||||||
|
QVERIFY(index != -1);
|
||||||
|
QMetaMethod voidSlotInt = testObject->metaObject()->method(index);
|
||||||
|
|
||||||
|
QVERIFY(testObject->voidSlotIntArgument() == -1);
|
||||||
|
QVERIFY(voidSlotInt.invoke(testObject.data(), Q_ARG(int, 123)));
|
||||||
|
QCOMPARE(testObject->voidSlotIntArgument(), 123);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QMetaObjectBuilder::usage_method()
|
||||||
|
{
|
||||||
|
QScopedPointer<TestObject> testObject(new TestObject);
|
||||||
|
|
||||||
|
int index = testObject->metaObject()->indexOfMethod("listInvokableQRealQString(qreal,QString)");
|
||||||
|
QVERIFY(index != -1);
|
||||||
|
QMetaMethod listInvokableQRealQString = testObject->metaObject()->method(index);
|
||||||
|
QVariantList list;
|
||||||
|
QVERIFY(listInvokableQRealQString.invoke(testObject.data(), Q_RETURN_ARG(QVariantList, list),
|
||||||
|
Q_ARG(qreal, 123.0), Q_ARG(QString, "ciao")));
|
||||||
|
QCOMPARE(list.size(), 2);
|
||||||
|
QCOMPARE(list.at(0).type(), QVariant::Type(QMetaType::QReal));
|
||||||
|
QCOMPARE(list.at(0).toDouble(), double(123));
|
||||||
|
QCOMPARE(list.at(1).type(), QVariant::String);
|
||||||
|
QCOMPARE(list.at(1).toString(), QString::fromLatin1("ciao"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QMetaObjectBuilder::usage_constructor()
|
||||||
|
{
|
||||||
|
QScopedPointer<TestObject> testObject(new TestObject);
|
||||||
|
|
||||||
|
QCOMPARE(testObject->metaObject()->constructorCount(), 2);
|
||||||
|
QScopedPointer<QObject> testInstance(testObject->metaObject()->newInstance());
|
||||||
|
QVERIFY(testInstance != 0);
|
||||||
|
QScopedPointer<QObject> testInstance2(testObject->metaObject()->newInstance(Q_ARG(QObject*, testInstance.data())));
|
||||||
|
QVERIFY(testInstance2 != 0);
|
||||||
|
QCOMPARE(testInstance2->parent(), testInstance.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QMetaObjectBuilder::usage_connect()
|
||||||
|
{
|
||||||
|
QScopedPointer<TestObject> testObject(new TestObject);
|
||||||
|
|
||||||
|
QVERIFY(QObject::connect(testObject.data(), SIGNAL(intPropChanged(int)),
|
||||||
|
testObject.data(), SLOT(voidSlotInt(int))));
|
||||||
|
|
||||||
|
QVERIFY(testObject->voidSlotIntArgument() == -1);
|
||||||
|
testObject->setProperty("intProp", 123);
|
||||||
|
QCOMPARE(testObject->voidSlotIntArgument(), 123);
|
||||||
|
|
||||||
|
QVERIFY(QObject::disconnect(testObject.data(), SIGNAL(intPropChanged(int)),
|
||||||
|
testObject.data(), SLOT(voidSlotInt(int))));
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QMetaObjectBuilder::usage_templateConnect()
|
||||||
|
{
|
||||||
|
QScopedPointer<TestObject> testObject(new TestObject);
|
||||||
|
|
||||||
|
QTest::ignoreMessage(QtWarningMsg, "QObject::connect: signal not found in QObject");
|
||||||
|
QMetaObject::Connection con = QObject::connect(testObject.data(), &TestObject::intPropChanged,
|
||||||
|
testObject.data(), &TestObject::voidSlotInt);
|
||||||
|
QEXPECT_FAIL("", "template-based connect() fails because meta-object is deduced at compile-time", Abort);
|
||||||
|
QVERIFY(con);
|
||||||
|
}
|
||||||
|
|
||||||
QTEST_MAIN(tst_QMetaObjectBuilder)
|
QTEST_MAIN(tst_QMetaObjectBuilder)
|
||||||
|
|
||||||
#include "tst_qmetaobjectbuilder.moc"
|
#include "tst_qmetaobjectbuilder.moc"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user