QObject: disconnect - document behavior with queued connections

QObject::disconnect does not cancel pending events. This can cause hard
to find bugs in application code, so we explicitly document and unit
test this behavior.

Task-number: QTBUG-127675
Change-Id: I5e94d60c27b9ce2dd2bceb832eb817b7eaa9cdcd
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 0681e720a9851f1873ce5a5f99b5567d2b418261)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Tim Blechmann 2024-08-07 13:57:42 +08:00 committed by Qt Cherry-pick Bot
parent 59a3f43031
commit c5a27f4cfe
3 changed files with 27 additions and 0 deletions

View File

@ -17,3 +17,9 @@ calls.
To avoid mismatches, store the connection handle returned by connect(), and use
it in the call to \l{disconnect(const QMetaObject::Connection &connection)}{disconnect()}.
//! [disconnect-mismatch]
//! [disconnect-queued]
\note If a \l{Qt::QueuedConnection}{queued connection} is disconnected,
already scheduled events may still be delivered, causing the receiver to
be called after the connection is disconnected.
//! [disconnect-queued]

View File

@ -3210,6 +3210,7 @@ QMetaObject::Connection QObject::connect(const QObject *sender, const QMetaMetho
\endlist
\include includes/qobject.qdocinc disconnect-mismatch
\include includes/qobject.qdocinc disconnect-queued
\nullptr may be used as a wildcard, meaning "any signal", "any receiving
object", or "any slot in the receiving object", respectively.
@ -3364,6 +3365,7 @@ bool QObject::disconnect(const QObject *sender, const char *signal,
\endlist
\include includes/qobject.qdocinc disconnect-mismatch
\include includes/qobject.qdocinc disconnect-queued
QMetaMethod() may be used as wildcard in the meaning "any signal" or "any slot in receiving object".
In the same way \nullptr can be used for \a receiver in the meaning "any receiving object".
@ -3439,6 +3441,7 @@ bool QObject::disconnect(const QObject *sender, const QMetaMethod &signal,
Disconnects \a signal from \a method of \a receiver.
\include includes/qobject.qdocinc disconnect-mismatch
\include includes/qobject.qdocinc disconnect-queued
A signal-slot connection is removed when either of the objects
involved are destroyed.
@ -3454,6 +3457,7 @@ bool QObject::disconnect(const QObject *sender, const QMetaMethod &signal,
method.
\include includes/qobject.qdocinc disconnect-mismatch
\include includes/qobject.qdocinc disconnect-queued
A signal-slot connection is removed when either of the objects
involved are destroyed.

View File

@ -155,6 +155,7 @@ private slots:
void emitToDestroyedClass();
void declarativeData();
void asyncCallbackHelper();
void disconnectQueuedConnection_pendingEventsAreDelivered();
};
struct QObjectCreatedOnShutdown
@ -8949,5 +8950,21 @@ void tst_QObject::asyncCallbackHelper()
}
}
void tst_QObject::disconnectQueuedConnection_pendingEventsAreDelivered()
{
SenderObject sender;
ReceiverObject receiver;
receiver.count_slot1 = 0;
QObject::connect(&sender, &SenderObject::signal1, &receiver, &ReceiverObject::slot1,
Qt::QueuedConnection);
sender.emitSignal1();
QCOMPARE(receiver.count_slot1, 0);
QObject::disconnect(&sender, &SenderObject::signal1, &receiver, &ReceiverObject::slot1);
QCOMPARE(receiver.count_slot1, 0);
QTRY_COMPARE(receiver.count_slot1, 1);
}
QTEST_MAIN(tst_QObject)
#include "tst_qobject.moc"