In QML (6.4), I have a TextField left of a ComboBox. My users want to fill the TextField with the numpad and for ease of use, when they press the Enter key (the one on the numpad), they want to automatically focus the next input element, which is the ComboBox. I am handling that with Keys.onEnterPressed on the TextField and I use forceActiveFocus() to set the focus on the ComboBox.
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
ApplicationWindow {
height: 400
visibility: Window.Windowed
visible: true
width: 600
RowLayout {
anchors.fill: parent
TextField {
Layout.fillWidth: true
Layout.preferredHeight: 30
Keys.onEnterPressed: combo.forceActiveFocus()
}
ComboBox {
id: combo
Layout.fillWidth: true
Layout.preferredHeight: 30
model: ['option 1', 'option 2']
}
}
}
When I enter some text in the TextField and press Tab, the combo gets focus. When I press Enter (on the numpad) instead of Tab, the ComboBox gets focus and aditionally opens its popup (the dropdown list).
I tried to set the event.handled to true, but the situation remains identical
Keys.onEnterPressed: function (event) {
event.handled = true
combo.forceActiveFocus();
}
I also tried adding Keys.onTabPressed: combo.forceActiveFocus()
to the TextField as well to see if forceActiveFocus was causing this behaviour, but here the popup also opens after Enter, while it does not after pressing Tab.
Then I tried combo.forceActiveFocus(Qt.TabFocusReason)
, also to no avail.
My intended behaviour is for Enter to behave like Tab (that is, only focus the ComboBox but not opening the popup/dropdown). Is there a way to achieve that?
[EDIT/REWRITE]
After playing a bit more, I found a better solution:
TextField {
Keys.onReleased: function (event) {
if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) {
event.accepted = true;
combo.forceActiveFocus();
}
}
}
The thinking behind this is when you press the enter key you get both Keys.onPressed
and Keys.onReleased
signals. The TextField
receives the Keys.onPressed
signal but, because you change active focus the ComboBox
receives the Keys.onReleased
signal. So the solution is to move the event handling from Keys.onPressed
to Keys.onReleased
. That way, the TextField
will receive both Keys.onPressed
and Keys.onReleased
signals and you change focus during the latter signal.
[ORIGINAL WORKAROUND SOLUTION]
I was able to reproduce the problem in Qt6.4. I found a workaround using a Timer.
TextField {
Keys.onEnterPressed: nextTimer.restart()
Keys.onReturnPressed: nextTimer.restart()
}
Timer {
id: nextTimer
interval: 200
onTriggered: combo.forceActiveFocus()
}
If the Timer's interval is set to 100 or lower, the problem appears again. Increasing the interval to 200 or above the problem goes away. The reason why this works is it takes me about 200ms for me to press and release the enter key. The Keys.onPressed
gets fired first, the input focus is changed, then, we wait until Keys.onReleased
is finished before the timer gets triggered. This is why the workaround works.