QComboBox: don't eat non-printable key strokes

QComboBox in non-editable mode passes all keyboard input to the internal
item search. This was done regardless if the character is printable or
not and therefore e.g. '\t' composed by Key_Tab + ControlModifier was
accepted and not passed to the parent (in the bug report to the
QTabWidget which could not switch tabs due to that).

Pick-to: 6.6 6.5
Fixes: QTBUG-118605
Change-Id: If39423587460a70231c735df4912b72c5ae77475
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
Christian Ehrlicher 2023-11-21 18:50:28 +01:00
parent 2da43b563e
commit 1ffd12a8dc
2 changed files with 30 additions and 5 deletions

View File

@ -3315,8 +3315,9 @@ void QComboBox::keyPressEvent(QKeyEvent *e)
#endif #endif
if (!d->lineEdit) { if (!d->lineEdit) {
if (!e->text().isEmpty()) const auto text = e->text();
d->keyboardSearchString(e->text()); if (!text.isEmpty() && text.at(0).isPrint())
d->keyboardSearchString(text);
else else
e->ignore(); e->ignore();
} }

View File

@ -3205,31 +3205,55 @@ void tst_QComboBox::task_QTBUG_54191_slotOnEditTextChangedSetsComboBoxToReadOnly
QCOMPARE(cb.currentIndex(), 1); QCOMPARE(cb.currentIndex(), 1);
} }
class ComboBox : public QComboBox {
public:
using QComboBox::QComboBox;
void keyPressEvent(QKeyEvent *e) override
{
QComboBox::keyPressEvent(e);
accepted = e->isAccepted();
}
bool accepted = false;
};
void tst_QComboBox::keyboardSelection() void tst_QComboBox::keyboardSelection()
{ {
QComboBox comboBox; ComboBox comboBox;
const int keyboardInterval = QApplication::keyboardInputInterval(); const int keyboardInterval = QApplication::keyboardInputInterval();
QStringList list; const QStringList list = {"OA", "OB", "OC", "OO", "OP", "PP"};
list << "OA" << "OB" << "OC" << "OO" << "OP" << "PP";
comboBox.addItems(list); comboBox.addItems(list);
// Clear any remaining keyboard input from previous tests. // Clear any remaining keyboard input from previous tests.
QTest::qWait(keyboardInterval); QTest::qWait(keyboardInterval);
QTest::keyClicks(&comboBox, "oo", Qt::NoModifier, 50); QTest::keyClicks(&comboBox, "oo", Qt::NoModifier, 50);
QCOMPARE(comboBox.currentText(), list.at(3)); QCOMPARE(comboBox.currentText(), list.at(3));
QCOMPARE(comboBox.accepted, true);
QTest::qWait(keyboardInterval); QTest::qWait(keyboardInterval);
QTest::keyClicks(&comboBox, "op", Qt::NoModifier, 50); QTest::keyClicks(&comboBox, "op", Qt::NoModifier, 50);
QCOMPARE(comboBox.currentText(), list.at(4)); QCOMPARE(comboBox.currentText(), list.at(4));
QCOMPARE(comboBox.accepted, true);
QTest::keyClick(&comboBox, Qt::Key_P, Qt::NoModifier, keyboardInterval); QTest::keyClick(&comboBox, Qt::Key_P, Qt::NoModifier, keyboardInterval);
QCOMPARE(comboBox.currentText(), list.at(5)); QCOMPARE(comboBox.currentText(), list.at(5));
QCOMPARE(comboBox.accepted, true);
QTest::keyClick(&comboBox, Qt::Key_O, Qt::NoModifier, keyboardInterval); QTest::keyClick(&comboBox, Qt::Key_O, Qt::NoModifier, keyboardInterval);
QCOMPARE(comboBox.currentText(), list.at(0)); QCOMPARE(comboBox.currentText(), list.at(0));
QCOMPARE(comboBox.accepted, true);
QTest::keyClick(&comboBox, Qt::Key_O, Qt::NoModifier, keyboardInterval); QTest::keyClick(&comboBox, Qt::Key_O, Qt::NoModifier, keyboardInterval);
QCOMPARE(comboBox.currentText(), list.at(1)); QCOMPARE(comboBox.currentText(), list.at(1));
QCOMPARE(comboBox.accepted, true);
QTest::keyClick(&comboBox, Qt::Key_Tab, Qt::NoModifier, keyboardInterval);
QCOMPARE(comboBox.currentText(), list.at(1));
QCOMPARE(comboBox.accepted, false);
QTest::keyClick(&comboBox, Qt::Key_Tab, Qt::ControlModifier, keyboardInterval);
QCOMPARE(comboBox.currentText(), list.at(1));
QCOMPARE(comboBox.accepted, false);
} }
void tst_QComboBox::updateDelegateOnEditableChange() void tst_QComboBox::updateDelegateOnEditableChange()