Fix disconnect()ing from signals declared in a base class

Fix disconnection from pointer to member signal that belongs to the base
class, but whose type is a pointer to a member of the derived class.

Commit 9cc106d9d7 fixed connect, so apply
the same fix in disconnect

[ChangeLog][QtCore][QObject] Fixed disconnecting from pointer to member
signal that belongs in the base class but whose type is explicitly given
as a pointer to a member in the derived class

Task-number: QTBUG-40638
Change-Id: Ia546fc8f36e1ea0dd0645bdd820aea47f43677ac
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Olivier Goffart 2014-08-08 10:26:03 +02:00
parent 5a882d0359
commit c2badc7423
2 changed files with 20 additions and 4 deletions

View File

@ -4711,10 +4711,14 @@ bool QObject::disconnectImpl(const QObject *sender, void **signal, const QObject
int signal_index = -1;
if (signal) {
void *args[] = { &signal_index, signal };
senderMetaObject->static_metacall(QMetaObject::IndexOfMethod, 0, args);
if (signal_index < 0 || signal_index >= QMetaObjectPrivate::get(senderMetaObject)->signalCount) {
qWarning("QObject::disconnect: signal not found in %s", senderMetaObject->className());
return false;
for (; senderMetaObject && signal_index < 0; senderMetaObject = senderMetaObject->superClass()) {
senderMetaObject->static_metacall(QMetaObject::IndexOfMethod, 0, args);
if (signal_index >= 0 && signal_index < QMetaObjectPrivate::get(senderMetaObject)->signalCount)
break;
}
if (!senderMetaObject) {
qWarning("QObject::disconnect: signal not found in %s", sender->metaObject()->className());
return QMetaObject::Connection(0);
}
signal_index += QMetaObjectPrivate::signalOffset(senderMetaObject);
}

View File

@ -6169,6 +6169,18 @@ void tst_QObject::connectBase()
QCOMPARE( r1.count_slot1, 1 );
QCOMPARE( r1.count_slot2, 1 );
QCOMPARE( r1.count_slot3, 1 );
QVERIFY( QObject::disconnect( &sub, &SubSender::signal1 , &r1, &ReceiverObject::slot1 ) );
QVERIFY( QObject::disconnect( &sub, static_cast<void (SenderObject::*)()>(&SubSender::signal2) , &r1, &ReceiverObject::slot2 ) );
QVERIFY( QObject::disconnect( &sub, static_cast<void (SubSender::*)()>(&SubSender::signal3) , &r1, &ReceiverObject::slot3 ) );
sub.emitSignal1();
sub.emitSignal2();
sub.emitSignal3();
QCOMPARE( r1.count_slot1, 1 );
QCOMPARE( r1.count_slot2, 1 );
QCOMPARE( r1.count_slot3, 1 );
}
struct QmlReceiver : public QtPrivate::QSlotObjectBase