Skip to content

Commit

Permalink
QObject: disconnect - document behavior with queued connections
Browse files Browse the repository at this point in the history
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 <[email protected]>
Reviewed-by: Leena Miettinen <[email protected]>
Reviewed-by: Thiago Macieira <[email protected]>
(cherry picked from commit 0681e72)
Reviewed-by: Qt Cherry-pick Bot <[email protected]>
  • Loading branch information
timblechmann authored and Qt Cherry-pick Bot committed Sep 20, 2024
1 parent 59a3f43 commit c5a27f4
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/corelib/doc/src/includes/qobject.qdocinc
Original file line number Diff line number Diff line change
Expand Up @@ -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]
4 changes: 4 additions & 0 deletions src/corelib/kernel/qobject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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".
Expand Down Expand Up @@ -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.
Expand All @@ -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.
Expand Down
17 changes: 17 additions & 0 deletions tests/auto/corelib/kernel/qobject/tst_qobject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ private slots:
void emitToDestroyedClass();
void declarativeData();
void asyncCallbackHelper();
void disconnectQueuedConnection_pendingEventsAreDelivered();
};

struct QObjectCreatedOnShutdown
Expand Down Expand Up @@ -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"

0 comments on commit c5a27f4

Please sign in to comment.