Focus - Strange behaviors, sometimes the focus become inconsistent
-
I noticed that sometimes the focus behaves strangely in my application, for a reason I cannot figure out.
For example, let consider the below code:
Window { width: 640 height: 480 title: qsTr("Focus") FocusScope { id: fsScope anchors.fill: parent Rectangle { anchors.fill: parent color: fsScope.focus ? "#ddddff" : "transparent" } MouseArea { anchors.fill: parent; onClicked: { fsScope.focus = true } } } Rectangle { anchors.fill: parent color: "transparent" Rectangle { anchors.left: parent.left anchors.top: parent.top anchors.right: parent.right anchors.margins: 10 height: txSimpleTextEdit.height color: "#d0d0d0" } TextInput { id: txSimpleTextEdit anchors.left: parent.left anchors.top: parent.top anchors.right: parent.right anchors.margins: 10 font.pixelSize: 15 selectByMouse: true activeFocusOnTab: true activeFocusOnPress: true focus: true } Rectangle { anchors.left: parent.left anchors.right: parent.right anchors.bottom: parent.bottom anchors.margins: 10 height: 35 color: "#d0d0d0" Button { id: btSimpleOk text: "Ok" anchors.top: parent.top anchors.right: parent.right anchors.bottom: parent.bottom anchors.margins: 5 } Button { text: "Cancel" anchors.top: parent.top anchors.right: btSimpleOk.left anchors.bottom: parent.bottom anchors.margins: 5 } } } }
In this code all works as expected
- The focus is set to the
TextInput
by default - The both Tab and Shift Tab keys are working, and the focus is passing in a circular way (i.e it returns to the first component after the last one was tabbed)
- The focus is passing to the next component even if the background is focused, or even if no component was previously focused
- The background never receives the focus when the Tab key is pressed
- Any component loses the focus if the background is clicked
But if I modify the code this way
Window { width: 640 height: 480 title: qsTr("Focus") Rectangle { anchors.fill: parent color: "transparent" SwipeView { anchors.fill: parent Page { background: Rectangle { anchors.fill: parent color: "transparent" } FocusScope { id: fsSwipeViewScope anchors.fill: parent Rectangle { anchors.fill: parent color: fsSwipeViewScope.focus ? "#ffdddd" : "transparent" } MouseArea { anchors.fill: parent; onClicked: { fsSwipeViewScope.focus = true } } } Rectangle { anchors.left: parent.left anchors.top: parent.top anchors.right: parent.right anchors.margins: 10 height: txTextEdit.height color: "#d0d0d0" } TextInput { id: txTextEdit anchors.left: parent.left anchors.top: parent.top anchors.right: parent.right anchors.margins: 10 font.pixelSize: 15 selectByMouse: true activeFocusOnTab: true activeFocusOnPress: true focus: true } Rectangle { anchors.left: parent.left anchors.right: parent.right anchors.bottom: parent.bottom anchors.margins: 10 height: 35 color: "#d0d0d0" Button { id: btOk text: "Ok" anchors.top: parent.top anchors.right: parent.right anchors.bottom: parent.bottom anchors.margins: 5 } Button { text: "Cancel" anchors.top: parent.top anchors.right: btOk.left anchors.bottom: parent.bottom anchors.margins: 5 } } } } } }
Then several issues appear
- The
TextInput
component is no longer selected by default (and there is NO WAY to select it, at least I found none) - The Tab key hangs after the Cancel button, and refuse to return to the first component, whereas the Shift Tab behavior remains normal
- By default the Tab key do nothing, until a component is selected
You may notice that the both code are similar, I only added a
SwipeView
component between the backgroundRectangle
and the other components.So I have several questions
- Why the focus behavior differs so much if a
SwipeView
is used? - How can I modify the 2nd code to make it to work as the first one?
- What are my mistakes in the above code? Why the 2nd does no longer work as expected?
- What are the good practices and correct rules to apply to maintain a well working focus?
- The focus is set to the
-
According to Focus Management in Qt Quick Controls, both SwipeView and Page act as focus scopes. In the second example, I don't see any explicit setting of focus in either one. If I assign ids to both of them, and bind txTextEdit to
swipeView.focus + " " + page.focus
, the initial value I see is "false true". Assigning true to swipeView.focus causes txTextEdit to have active focus.Without assigning focus to the SwipeView, clicking on the TextEdit causes the SwipeView to gain focus. The same thing happens with an initial tab press. Tabbing again goes to the OK Button, and then to Cancel. It doesn't continue cycling after that. Shift-tab runs in the reverse order, and does cycle. I'm not sure what causes the difference. Adding
KeyNavigation.tab: txTextEdit
to the cancel button allows navigation with tab to loop.This is with Qt 5.15.0 on macOS, QtQuick 2.15, QtQuick.Window 2.15, and QtQuick.Controls 2.12. It's possible that other versions have different intentional, undefined, or defective behavior.