tabbing between TextFields defined by a Repeater
-
Hi all -
I'm trying to code an IPv4 input module. I'm using a Repeater for the 4 bytes, with an inline delegate:
Repeater { id: repeater model: 4 delegate: RowLayout { TextField { activeFocusOnTab: true Layout.preferredHeight: 40 Layout.preferredWidth: 60 validator: IntValidator { bottom: 0; top: 255 } Keys.onTabPressed: (event) => { if (acceptableInput) { var nextTabIndex = index < 3 ? index + 1 : 0 repeater.itemAt(nextTabIndex).forceActiveFocus() } } } Text { text: "." visible: index < 3 } } }
I'd expect the tab key to move among the various TextFields, but it doesn't. Can someone see what I'm doing wrong?
Thanks...
-
Hi,
I've taken the pleasure of modifying it a bit because I couldn't see anything with the code snippet.
I think this is what you want:
import QtQuick import QtQuick.Controls import QtQuick.Layouts Window { id: root width: 1920 height: 1080 RowLayout { id: parentRow Repeater { id: repeater model: 4 delegate: Row { required property int index spacing: parentRow.spacing Layout.preferredHeight: 40 TextField { id: text_field activeFocusOnTab: true text: index validator: IntValidator { bottom: 0 top: 255 } Keys.onTabPressed: { console.log("here we go!") nextItemInFocusChain().forceActiveFocus() } } Text { id: label text: "." visible: index < 3 anchors.verticalCenter: parent.verticalCenter } } } } }
-
-
Thank you both. I've added a modal dialog for when input isn't acceptable, but somehow the TextFields in the Repeater are still accepting navigation and input keystrokes. I'm providing a stripped-down example:
import QtQuick import QtQuick.Controls import QtQuick.Layouts Window { id: mainWindow width: 640 height: 480 visible: true RowLayout { anchors.fill: parent Repeater { id: repeater model: 4 delegate: RowLayout { TextField { id: inputField validator: IntValidator { bottom: 0; top: 255 } Keys.onPressed: (event) => { if (errorDialog.visible) { event.accepted = false } else { if (event.key === Qt.Key_Tab) { if (acceptableInput) { nextItemInFocusChain(true).forceActiveFocus() } else { errorDialog.open() } } } } } Text { text: "." visible: index < 3 } } } } Dialog { id: errorDialog modal: true standardButtons: Dialog.Ok } }
Any idea why the "modal" property of the dialog isn't blocking keyboard input?
Thanks...
-
You need to accept the event for this to not be propagated like
Keys.onPressed: (event) => { if (event.key === Qt.Key_Tab) { if (acceptableInput) { nextItemInFocusChain(true).forceActiveFocus() } else { event.accepted = true } } }
If you find our answers useful please consider giving us an upvote.
You can test it here -
-
Thanks for the answer. Now, how can I get my dialog to close when the user presses return or enter? I've tried this:
Dialog { parent: Overlay.overlay modal: true focus: true standardButtons: Dialog.Ok Item { anchors.fill: parent Keys.onReturnPressed: close() } }
But that doesn't work.
Thanks...
-
import QtQuick import QtQuick.Controls import QtQuick.Layouts Window { id: mainWindow width: 640 height: 480 visible: true RowLayout { anchors.fill: parent Repeater { id: repeater model: 4 delegate: RowLayout { TextField { id: inputField validator: IntValidator { bottom: 0; top: 255 } Keys.onPressed: (event) => { if (event.key === Qt.Key_Tab) { if (acceptableInput) { nextItemInFocusChain(true).forceActiveFocus() } else { errorDialog.open() } event.accepted = true } } } Text { text: "." visible: index < 3 } } } } Dialog { id: errorDialog parent: Overlay.overlay modal: true onOpened: keycatcher.focus=true standardButtons: Dialog.Ok Item { id: keycatcher anchors.fill: parent Keys.onReturnPressed: errorDialog.close() } } }
you can test it here