QQmlMetaType: Don't duplicate notify signals for extended types

We have to add the methods first, so that the properties can be
associated with their proper notification signals once we add them. If
we add the properties first, the "missing" notification signals are
synthesized.

Pick-to: 6.2 6.3
Fixes: QTBUG-101155
Change-Id: I1aacbf33a24f7a98d05dece77c804bd7cba8a041
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
Ulf Hermann 2022-02-23 12:17:44 +01:00
parent c8e756e560
commit 57614680f7
4 changed files with 43 additions and 17 deletions

View File

@ -253,20 +253,7 @@ void QQmlMetaType::clone(QMetaObjectBuilder &builder, const QMetaObject *mo,
}
}
// Clone Q_PROPERTY
for (int ii = mo->propertyOffset(); ii < mo->propertyCount(); ++ii) {
QMetaProperty property = mo->property(ii);
int otherIndex = ignoreEnd->indexOfProperty(property.name());
if (otherIndex >= ignoreStart->propertyOffset() + ignoreStart->propertyCount()) {
builder.addProperty(QByteArray("__qml_ignore__") + property.name(), QByteArray("void"));
// Skip
} else {
builder.addProperty(property);
}
}
// Clone Q_METHODS
// Clone Q_METHODS - do this first to avoid duplicating the notify signals.
for (int ii = mo->methodOffset(); ii < mo->methodCount(); ++ii) {
QMetaMethod method = mo->method(ii);
@ -290,6 +277,19 @@ void QQmlMetaType::clone(QMetaObjectBuilder &builder, const QMetaObject *mo,
m.setAccess(QMetaMethod::Private);
}
// Clone Q_PROPERTY
for (int ii = mo->propertyOffset(); ii < mo->propertyCount(); ++ii) {
QMetaProperty property = mo->property(ii);
int otherIndex = ignoreEnd->indexOfProperty(property.name());
if (otherIndex >= ignoreStart->propertyOffset() + ignoreStart->propertyCount()) {
builder.addProperty(QByteArray("__qml_ignore__") + property.name(), QByteArray("void"));
// Skip
} else {
builder.addProperty(property);
}
}
// Clone Q_ENUMS
for (int ii = mo->enumeratorOffset(); ii < mo->enumeratorCount(); ++ii) {
QMetaEnum enumerator = mo->enumerator(ii);

View File

@ -5,12 +5,17 @@ QtObject {
property Foreign foreign: Foreign {
objectName: "foreign"
}
property Extended extended: Extended {}
property Extended extended: Extended {
objectName: "extended"
property int changeCount: 0
onExtensionChanged: ++changeCount
}
property ForeignExtended foreignExtended: ForeignExtended {
objectName: "foreignExtended"
}
property int extendedBase: extended.base
property int extendedChangeCount: extended.changeCount
property int extendedInvokable: extended.invokable()
property int extendedSlot: extended.slot()

View File

@ -1470,13 +1470,23 @@ public:
class Extension : public QObject
{
Q_OBJECT
Q_PROPERTY(int extension READ extension CONSTANT)
Q_PROPERTY(int extension READ extension WRITE setExtension NOTIFY extensionChanged FINAL)
public:
Extension(QObject *parent = nullptr) : QObject(parent) {}
int extension() const { return 42; }
int extension() const { return ext; }
void setExtension(int e) {
if (e != ext) {
ext = e;
emit extensionChanged();
}
}
Q_INVOKABLE int invokable() { return 123; }
Q_SIGNALS:
void extensionChanged();
public slots:
int slot() { return 456; }
private:
int ext = 42;
};
class Extended : public QObject

View File

@ -5636,9 +5636,20 @@ void tst_qqmllanguage::extendedForeignTypes()
QScopedPointer<QObject> o(component.create());
QVERIFY(!o.isNull());
QObject *extended = o->property("extended").value<QObject *>();
QVERIFY(extended);
QSignalSpy extensionChangedSpy(extended, SIGNAL(extensionChanged()));
QCOMPARE(o->property("extendedBase").toInt(), 43);
QCOMPARE(o->property("extendedExtension").toInt(), 42);
QCOMPARE(o->property("foreignExtendedExtension").toInt(), 42);
QCOMPARE(extensionChangedSpy.count(), 0);
extended->setProperty("extension", 44);
QCOMPARE(extensionChangedSpy.count(), 1);
QCOMPARE(o->property("extendedChangeCount").toInt(), 1);
QCOMPARE(o->property("extendedExtension").toInt(), 44);
QCOMPARE(o->property("foreignObjectName").toString(), QLatin1String("foreign"));
QCOMPARE(o->property("foreignExtendedObjectName").toString(), QLatin1String("foreignExtended"));
QCOMPARE(o->property("extendedInvokable").toInt(), 123);