Implement helper function for handling key events in QGroupBox

A GroupBox would for its' checkbox accept a key event if this event
was a part of buttonPressKeys. This would even happen if the QGroupBox
wasn't checkable, which resulted with an unnecessarily consumed
key event.

Implement a helper function QGroupBoxPrivate::shouldHandleKeyEvent()
that can be used to check if a key event should be accepted,
and that takes into consideration if the QGroupBox is checkable.

Fixes: QTBUG-129095
Change-Id: I21d1aa24b1b25b70d5274e2c13f887aefc80dbc5
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
This commit is contained in:
Chris Lerner 2024-10-29 14:29:06 +01:00
parent 1edea2defc
commit 5d397a262f
2 changed files with 26 additions and 8 deletions

View File

@ -43,6 +43,7 @@ public:
void _q_fixFocus(Qt::FocusReason reason); void _q_fixFocus(Qt::FocusReason reason);
void _q_setChildrenEnabled(bool b); void _q_setChildrenEnabled(bool b);
void click(); void click();
bool shouldHandleKeyEvent(const QKeyEvent *keyEvent) const;
bool flat; bool flat;
bool checkable; bool checkable;
bool checked; bool checked;
@ -327,10 +328,7 @@ bool QGroupBox::event(QEvent *e)
return true; return true;
case QEvent::KeyPress: { case QEvent::KeyPress: {
QKeyEvent *k = static_cast<QKeyEvent*>(e); QKeyEvent *k = static_cast<QKeyEvent*>(e);
const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme() if (d->shouldHandleKeyEvent(k)) {
->themeHint(QPlatformTheme::ButtonPressKeys)
.value<QList<Qt::Key>>();
if (!k->isAutoRepeat() && buttonPressKeys.contains(k->key())) {
d->pressedControl = QStyle::SC_GroupBoxCheckBox; d->pressedControl = QStyle::SC_GroupBoxCheckBox;
update(style()->subControlRect(QStyle::CC_GroupBox, &box, QStyle::SC_GroupBoxCheckBox, this)); update(style()->subControlRect(QStyle::CC_GroupBox, &box, QStyle::SC_GroupBoxCheckBox, this));
return true; return true;
@ -339,10 +337,7 @@ bool QGroupBox::event(QEvent *e)
} }
case QEvent::KeyRelease: { case QEvent::KeyRelease: {
QKeyEvent *k = static_cast<QKeyEvent*>(e); QKeyEvent *k = static_cast<QKeyEvent*>(e);
const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme() if (d->shouldHandleKeyEvent(k)) {
->themeHint(QPlatformTheme::ButtonPressKeys)
.value<QList<Qt::Key>>();
if (!k->isAutoRepeat() && buttonPressKeys.contains(k->key())) {
bool toggle = (d->pressedControl == QStyle::SC_GroupBoxLabel bool toggle = (d->pressedControl == QStyle::SC_GroupBoxLabel
|| d->pressedControl == QStyle::SC_GroupBoxCheckBox); || d->pressedControl == QStyle::SC_GroupBoxCheckBox);
d->pressedControl = QStyle::SC_None; d->pressedControl = QStyle::SC_None;
@ -728,6 +723,22 @@ void QGroupBox::mouseReleaseEvent(QMouseEvent *event)
update(style()->subControlRect(QStyle::CC_GroupBox, &box, QStyle::SC_GroupBoxCheckBox, this)); update(style()->subControlRect(QStyle::CC_GroupBox, &box, QStyle::SC_GroupBoxCheckBox, this));
} }
bool QGroupBoxPrivate::shouldHandleKeyEvent(const QKeyEvent *keyEvent) const
{
Q_Q(const QGroupBox);
Q_ASSERT(q->isEnabled());
if (!q->isCheckable() || keyEvent->isAutoRepeat())
return false;
const QList<Qt::Key> buttonPressKeys = QGuiApplicationPrivate::platformTheme()
->themeHint(QPlatformTheme::ButtonPressKeys)
.value<QList<Qt::Key>>();
return buttonPressKeys.contains(keyEvent->key());
}
QT_END_NAMESPACE QT_END_NAMESPACE
#include "moc_qgroupbox.cpp" #include "moc_qgroupbox.cpp"

View File

@ -603,6 +603,13 @@ void tst_QGroupBox::buttonPressKeys()
QTest::keyClick(&groupBox, buttonPressKeys[i]); QTest::keyClick(&groupBox, buttonPressKeys[i]);
QCOMPARE(clickedSpy.size(), i + 1); QCOMPARE(clickedSpy.size(), i + 1);
} }
groupBox.setCheckable(false);
QSignalSpy notClickedSpy(&groupBox, &QGroupBox::clicked);
for (int i = 0; i < buttonPressKeys.size(); ++i) {
QTest::keyClick(&groupBox, buttonPressKeys[i]);
QCOMPARE(notClickedSpy.size(), 0);
}
} }
void tst_QGroupBox::sendMouseMoveEvent(QWidget *widget, const QPoint &localPos) void tst_QGroupBox::sendMouseMoveEvent(QWidget *widget, const QPoint &localPos)