Fix hiding in QComboBox when there is no selection

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
Pick-to: 6.5
Change-Id: I287af75d27e6f6ff969e4706e16cc8c4812129ea
Reviewed-by: Thorbjørn Lund Martsum <tmartsum@gmail.com>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
Volker Hilsheimer 2023-05-03 17:59:48 +02:00
parent 3dd3268ded
commit a43ca591c1
2 changed files with 53 additions and 18 deletions

View File

@ -2809,31 +2809,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();
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]{
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)
{

View File

@ -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"