How to make a "focus chain" of components when they are generated with a Repeater?
-
Hi,
The question/title of the post isn't very clear because I don't know how to word it better.
I'm blocking on trying to implement a form where the focus goes to the next TextInput/RadioButton when pressing a key. I'm generating the form via a Repeater component. Depending on the model a RadioButton or a TextInput (inside a Rectangle) is displayed.
This is a snippet of the code, this Repeater is nested inside a GridLayout.
Repeater { id: repeater model: ["int", "int", "int", "int", "int", "int", "string", "string", "int", "int", "int", "double", "bool", "bool", "bool", "string"] delegate: Item { Layout.column: 1 Layout.row: model.index Layout.preferredHeight: 50 Layout.preferredWidth: 200 Rectangle { anchors.fill: parent color: Constants.selectableElementColor radius: 30 visible: modelData === "int" || modelData === "double" || modelData === "string" TextInput { id: textInput anchors.fill: parent font.pixelSize: Constants.mediumTextPixelSize horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter focus: model.index === 0 } } RadioButton { autoExclusive: false anchors.fill: parent visible: modelData === "bool" focus: model.index === 0 } } }
I wonder if the "id: textInput" is correct? Since id must be unique, and the TextInput is in a Repeater will it cause problems? Because my first idea was to store a reference to each input component (if visible === true) but how can I assign them an id dynamically? I'm confused as to how to proceed.
I'm not new to programming, or Qt, but I'm new to QML and a bit lost on the details haha. Can anyone point me in the right direction?
-
Hi,
The question/title of the post isn't very clear because I don't know how to word it better.
I'm blocking on trying to implement a form where the focus goes to the next TextInput/RadioButton when pressing a key. I'm generating the form via a Repeater component. Depending on the model a RadioButton or a TextInput (inside a Rectangle) is displayed.
This is a snippet of the code, this Repeater is nested inside a GridLayout.
Repeater { id: repeater model: ["int", "int", "int", "int", "int", "int", "string", "string", "int", "int", "int", "double", "bool", "bool", "bool", "string"] delegate: Item { Layout.column: 1 Layout.row: model.index Layout.preferredHeight: 50 Layout.preferredWidth: 200 Rectangle { anchors.fill: parent color: Constants.selectableElementColor radius: 30 visible: modelData === "int" || modelData === "double" || modelData === "string" TextInput { id: textInput anchors.fill: parent font.pixelSize: Constants.mediumTextPixelSize horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter focus: model.index === 0 } } RadioButton { autoExclusive: false anchors.fill: parent visible: modelData === "bool" focus: model.index === 0 } } }
I wonder if the "id: textInput" is correct? Since id must be unique, and the TextInput is in a Repeater will it cause problems? Because my first idea was to store a reference to each input component (if visible === true) but how can I assign them an id dynamically? I'm confused as to how to proceed.
I'm not new to programming, or Qt, but I'm new to QML and a bit lost on the details haha. Can anyone point me in the right direction?
@t-vanbesien said in How to make a "focus chain" of components when they are generated with a Repeater?:
the focus goes to the next TextInput/RadioButton when pressing a key
If you are talking about tab navigation (the "classic" experience that people who hate mousing/trackpadding are expecting from well-behaved apps), then this will probably explain what you need to know:
https://www.219design.com/a-tale-of-efficient-keyboard-navigation-code-in-qml/
The blog post contains code in a screenshot (terrible). I apologize. Please note: the blog also contains links to the raw code: https://github.com/219-design/keyboard-focus-and-navigation-in-qml
The "solution" shows something like this:
Widget { color: "yellow" focus: true } Widget { color: "orange" } Widget { color: "green" } Widget { color: "red" }
^^ It will work if inside a Repeater, too.
-
If tab navigation (like what is described in the blog post I shared) is indeed what you want, and if you still cannot quite achieve it after reading the post, then try to post here a minimal runnable QML sample (de-coupled from any C++ or python PyQt backend that you might have). Note that "minimal runnable" just means I can launch the code easily, whether or not the keyboard navigation features are working or not.
-
@t-vanbesien said in How to make a "focus chain" of components when they are generated with a Repeater?:
the focus goes to the next TextInput/RadioButton when pressing a key
If you are talking about tab navigation (the "classic" experience that people who hate mousing/trackpadding are expecting from well-behaved apps), then this will probably explain what you need to know:
https://www.219design.com/a-tale-of-efficient-keyboard-navigation-code-in-qml/
The blog post contains code in a screenshot (terrible). I apologize. Please note: the blog also contains links to the raw code: https://github.com/219-design/keyboard-focus-and-navigation-in-qml
The "solution" shows something like this:
Widget { color: "yellow" focus: true } Widget { color: "orange" } Widget { color: "green" } Widget { color: "red" }
^^ It will work if inside a Repeater, too.
@KH-219Design Interesting blog post. Thanks.
The code in the post demonstrates defining KeyNavigation.tab and KeyNavigation.backTab. If backTab is intended to run a cycle in the opposite direction, defining it isn't necessary.
https://doc.qt.io/qt-5/qml-qtquick-keynavigation.html#details:KeyNavigation will implicitly set the other direction to return focus to this item. So if you set left to another item, right will be set on that item's KeyNavigation to set focus back to this item. However, if that item's KeyNavigation has had right explicitly set then no change will occur. This means that the example above could achieve the same behavior without specifying KeyNavigation.right or KeyNavigation.down for any of the items.
There's also the activeFocusOnTab property.
https://doc.qt.io/qt-5/qml-qtquick-item.html#activeFocusOnTab-propThis property holds whether the item wants to be in the tab focus chain. By default, this is set to false.
As of Qt 6.7, Item has gained the focusPolicy property.
https://doc.qt.io/qt-6/qml-qtquick-item.html#focusPolicy-prop -
@KH-219Design Thanks for the links, I think I'll find what I need there. I'll try to implement all this and come back here to set the post as answered if I manage!