From f83f4badce46b5572fa4c85ba2c3420a19d28450 Mon Sep 17 00:00:00 2001 From: Andrei Golubev Date: Fri, 15 Jan 2021 09:42:19 +0100 Subject: Add new special QObjectPrivate::{connect, disconnect} for QML Original QML-specific connection mechanism ignores the receiver argument and uses sender as receiver. This causes uncontrollable memory growth in certain cases as connections on receiver persist even after receiver is destroyed New connect() with receiver parameter uses underlying API correctly, disconnect is provided for the symmetry (not sure it's really needed) Task-number: QTBUG-86368 Change-Id: I4580d75b617cb2c4dfb971a4dfb8e943e325572b Reviewed-by: Fabian Kosmale Reviewed-by: Thiago Macieira (cherry picked from commit 6f520abdab7120789800208dde837b3836f762cc) Reviewed-by: Qt Cherry-pick Bot --- tests/auto/corelib/kernel/qobject/tst_qobject.cpp | 28 +++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'tests') diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index 5cf1f0e50f..68d90987e1 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -149,6 +149,7 @@ private slots: void connectBase(); void connectWarnings(); void qmlConnect(); + void qmlConnectToQObjectReceiver(); void exceptions(); void noDeclarativeParentChangedOnDestruction(); void deleteLaterInAboutToBlockHandler(); @@ -6787,6 +6788,33 @@ void tst_QObject::qmlConnect() #endif } +void tst_QObject::qmlConnectToQObjectReceiver() +{ +#ifdef QT_BUILD_INTERNAL + SenderObject sender; + QScopedPointer receiver(new QObject); + QmlReceiver *slotObject = new QmlReceiver; + slotObject->magic = slotObject; + slotObject->ref(); // extra ref so that slot object is not implicitly deleted + + QVERIFY(QObjectPrivate::connect(&sender, sender.metaObject()->indexOfSignal("signal1()"), + receiver.get(), slotObject, Qt::AutoConnection)); + + QCOMPARE(slotObject->callCount, 0); + sender.emitSignal1(); + QCOMPARE(slotObject->callCount, 1); + + receiver.reset(); // this should disconnect the slotObject + + sender.emitSignal1(); + QCOMPARE(slotObject->callCount, 1); + + slotObject->destroyIfLastRef(); +#else + QSKIP("Needs QT_BUILD_INTERNAL"); +#endif +} + #ifndef QT_NO_EXCEPTIONS class ObjectException : public std::exception { }; -- cgit v1.2.3