diff --git a/src/widgets/widgets/qtoolbutton.cpp b/src/widgets/widgets/qtoolbutton.cpp index f3e3c8261e9..e0775afd265 100644 --- a/src/widgets/widgets/qtoolbutton.cpp +++ b/src/widgets/widgets/qtoolbutton.cpp @@ -584,8 +584,10 @@ void QToolButton::mousePressEvent(QMouseEvent *e) void QToolButton::mouseReleaseEvent(QMouseEvent *e) { Q_D(QToolButton); + QPointer guard(this); QAbstractButton::mouseReleaseEvent(e); - d->buttonPressed = QToolButtonPrivate::NoButtonPressed; + if (guard) + d->buttonPressed = QToolButtonPrivate::NoButtonPressed; } /*! diff --git a/tests/auto/widgets/widgets/qtoolbutton/tst_qtoolbutton.cpp b/tests/auto/widgets/widgets/qtoolbutton/tst_qtoolbutton.cpp index 30224323dcf..20472861d97 100644 --- a/tests/auto/widgets/widgets/qtoolbutton/tst_qtoolbutton.cpp +++ b/tests/auto/widgets/widgets/qtoolbutton/tst_qtoolbutton.cpp @@ -34,6 +34,7 @@ private slots: void qtbug_26956_popupTimerDone(); void qtbug_34759_sizeHintResetWhenSettingMenu(); void defaultActionSynced(); + void deleteInHandler(); protected slots: void sendMouseClick(); @@ -316,5 +317,22 @@ void tst_QToolButton::defaultActionSynced() QCOMPARE(bSpy.size(), ++bToggledCount); } +void tst_QToolButton::deleteInHandler() +{ + // Tests that if something deletes the button + // while its event handler is still on the callstack, we don't crash + + QPointer tb = new QToolButton(); + tb->show(); + QVERIFY(QTest::qWaitForWindowActive(tb)); + + connect(tb, &QToolButton::clicked, this, [tb] { + delete tb; + }); + + QTest::mouseClick(tb, Qt::LeftButton); + QVERIFY(!tb); +} + QTEST_MAIN(tst_QToolButton) #include "tst_qtoolbutton.moc"