From b44dcfa1ee64b7a9036ab20597f107c14cce19dc Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Wed, 3 May 2023 17:59:48 +0200 Subject: Fix hiding in QComboBox when there is no selection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If there is an effect on the selected item we want to show it, but if there is no item to highligh we just close the combo. Fixes: QTBUG-113311 Change-Id: I287af75d27e6f6ff969e4706e16cc8c4812129ea Reviewed-by: Thorbjørn Lund Martsum Reviewed-by: Volker Hilsheimer (cherry picked from commit a43ca591c1835c27fd2acd63298c42f51b470f8e) --- src/widgets/widgets/qcombobox.cpp | 37 +++++++++++----------- .../widgets/widgets/qcombobox/tst_qcombobox.cpp | 36 +++++++++++++++++++++ 2 files changed, 54 insertions(+), 19 deletions(-) diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index 878642f86c..a0bdb644b2 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -2807,31 +2807,30 @@ void QComboBox::hidePopup() return; #if QT_CONFIG(effects) - // Flash selected/triggered item (if any). - if (style()->styleHint(QStyle::SH_Menu_FlashTriggeredItem)) { - QItemSelectionModel *selectionModel = d->container->itemView() - ? d->container->itemView()->selectionModel() : nullptr; - if (selectionModel && selectionModel->hasSelection()) { - const QItemSelection selection = selectionModel->selection(); - - QTimer::singleShot(0, d->container, [d, selection, selectionModel]{ + QItemSelectionModel *selectionModel = d->container->itemView() + ? d->container->itemView()->selectionModel() : nullptr; + // Flash selected/triggered item (if any) before hiding the popup. + if (style()->styleHint(QStyle::SH_Menu_FlashTriggeredItem) && + selectionModel && selectionModel->hasSelection()) { + const QItemSelection selection = selectionModel->selection(); + + QTimer::singleShot(0, d->container, [d, selection, selectionModel]{ + QSignalBlocker modelBlocker(d->model); + QSignalBlocker viewBlocker(d->container->itemView()); + QSignalBlocker containerBlocker(d->container); + + // Deselect item and wait 60 ms. + selectionModel->select(selection, QItemSelectionModel::Toggle); + QTimer::singleShot(60, d->container, [d, selection, selectionModel]{ QSignalBlocker modelBlocker(d->model); QSignalBlocker viewBlocker(d->container->itemView()); QSignalBlocker containerBlocker(d->container); - - // Deselect item and wait 60 ms. selectionModel->select(selection, QItemSelectionModel::Toggle); - QTimer::singleShot(60, d->container, [d, selection, selectionModel]{ - QSignalBlocker modelBlocker(d->model); - QSignalBlocker viewBlocker(d->container->itemView()); - QSignalBlocker containerBlocker(d->container); - selectionModel->select(selection, QItemSelectionModel::Toggle); - QTimer::singleShot(20, d->container, [d] { - d->doHidePopup(); - }); + QTimer::singleShot(20, d->container, [d] { + d->doHidePopup(); }); }); - } + }); } else #endif // QT_CONFIG(effects) { diff --git a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp index 245c4c8ca4..544100b888 100644 --- a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp +++ b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp @@ -152,6 +152,7 @@ private slots: void buttonPressKeys(); void clearModel(); void cancelClosesPopupNotDialog(); + void closePopupWithCheckableItems(); private: PlatformInputContext m_platformInputContext; @@ -3696,5 +3697,40 @@ void tst_QComboBox::cancelClosesPopupNotDialog() QVERIFY(!dialog.isVisible()); } +void tst_QComboBox::closePopupWithCheckableItems() +{ + QWidget widget; + + QVBoxLayout *vb = new QVBoxLayout(&widget); + + QLabel *dlgLabel = new QLabel("Click when combo expanded."); + vb->addWidget(dlgLabel); + + QComboBox *combo = new QComboBox(); + vb->addWidget(combo); + + QStandardItemModel model; + const int rowCount = 10; + for (int r = 0; r < rowCount; ++r) { + QString str = "Item: " + QString::number(r); + QStandardItem *item = new QStandardItem(str); + const bool isChecked = (r % 2); + + item->setData(isChecked ? Qt::Checked : Qt::Unchecked, Qt::CheckStateRole); + item->setFlags(Qt::ItemIsUserCheckable | (item->flags() & ~(Qt::ItemIsSelectable)) ); + model.appendRow(item); + } + + combo->setModel(&model); + + widget.show(); + QVERIFY(QTest::qWaitForWindowExposed(&widget)); + + QTest::mouseClick(widget.windowHandle(), Qt::LeftButton, {}, combo->geometry().center()); + QVERIFY(QTest::qWaitForWindowExposed(combo->view())); + QTest::mouseClick(widget.windowHandle(), Qt::LeftButton, {}, dlgLabel->geometry().center()); + QTRY_VERIFY(!combo->view()->isVisible()); +} + QTEST_MAIN(tst_QComboBox) #include "tst_qcombobox.moc" -- cgit v1.2.1