QDialogButtonGroup: Fix removal of deleted buttons

As the destroyed() signal is emitted from ~QObject, it is not allowed
to use static_cast to a QAbstractButton on that pointer anymore.
And the qobject_cast will also fail which will keep a dangling pointer
in the hash.

Change-Id: If0d22fcc30cde87e771e70914c3afb04ea207289
Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
This commit is contained in:
Olivier Goffart 2017-03-02 08:55:35 +01:00 committed by Olivier Goffart (Woboq GmbH)
parent 6965b8a592
commit 8387d87bdc
2 changed files with 21 additions and 3 deletions

View File

@ -716,8 +716,7 @@ void QDialogButtonBox::removeButton(QAbstractButton *button)
return;
// Remove it from the standard button hash first and then from the roles
if (QPushButton *pushButton = qobject_cast<QPushButton *>(button))
d->standardButtonHash.remove(pushButton);
d->standardButtonHash.remove(reinterpret_cast<QPushButton *>(button));
for (int i = 0; i < NRoles; ++i) {
QList<QAbstractButton *> &list = d->buttonLists[i];
for (int j = 0; j < list.count(); ++j) {
@ -883,7 +882,7 @@ void QDialogButtonBoxPrivate::_q_handleButtonDestroyed()
Q_Q(QDialogButtonBox);
if (QObject *object = q->sender()) {
QBoolBlocker skippy(internalRemove);
q->removeButton(static_cast<QAbstractButton *>(object));
q->removeButton(reinterpret_cast<QAbstractButton *>(object));
}
}

View File

@ -97,6 +97,8 @@ private slots:
void testDefaultButton();
void task191642_default();
void testDeletedStandardButton();
private:
qint64 timeStamp;
qint64 buttonClicked1TimeStamp;
@ -843,5 +845,22 @@ void tst_QDialogButtonBox::task191642_default()
QCOMPARE(clicked.count(), 1);
}
void tst_QDialogButtonBox::testDeletedStandardButton()
{
QDialogButtonBox buttonBox;
delete buttonBox.addButton(QDialogButtonBox::Ok);
QPointer<QPushButton> buttonC = buttonBox.addButton(QDialogButtonBox::Cancel);
delete buttonBox.addButton(QDialogButtonBox::Cancel);
QPointer<QPushButton> buttonA = buttonBox.addButton(QDialogButtonBox::Apply);
delete buttonBox.addButton(QDialogButtonBox::Help);
// A few button have been deleted, they should automatically be removed
QCOMPARE(buttonBox.standardButtons(), QDialogButtonBox::Apply | QDialogButtonBox::Cancel);
buttonBox.setStandardButtons(QDialogButtonBox::Reset | QDialogButtonBox::Cancel);
// setStanderdButton should delete previous buttons
QVERIFY(!buttonA);
QVERIFY(!buttonC);
}
QTEST_MAIN(tst_QDialogButtonBox)
#include "tst_qdialogbuttonbox.moc"