Qt 6.11 is out! See what's new in the release
blog
QML TableView simple keyboard navigation
-
I'm trying to add some simple keyboard navigation to my QML TableView. What I want is:
- Tab makes the input focus move to the right (this one seems to just work out of the box)
- When the user hits Enter, after calling the onEditingFinished callback, move the input focus down one row (this one I can't figure out how to do)
- Ideally implement this in the properties of the TableView widget itself, because I would like to encapsulate this behavior into a custom component.
Any working examples out there? So far my research hasn't turned anything up.
Thanks for reading.
-
Found part of the answer...
function updateFocus(row, column) { console.log("row " + row + " col " + column); if (row >= 0 && row < model.rowCount() && column >= 0 && column < model.columnCount()) { var cellPoint = Qt.point(column, row); datalogTableView.positionViewAtCell(cellPoint, TableView.Visible); datalogTableView.itemAtCell(cellPoint).forceActiveFocus(); } else console.log("skipped"); }This lets me set the focus at a given row/column coordinate. I can get the currently focused row/column from within the delegate. But I'm still searching for a way to get the row/column of the currently focused cell from the TableView widget itself.
-
import QtQuick import Qt.labs.qmlmodels Window { width: 640 height: 480 visible: true TableView { id: view anchors.fill: parent focus: true property Item currentItem: null model: TableModel { TableModelColumn { display: "a" } TableModelColumn { display: "b" } rows: [ { "a": 1, "b": 2 }, { "a": 3, "b": 4 } ] } Component.onCompleted: selectionModel.setCurrentIndex(model.index(0,0), ItemSelectionModel.Current) selectionModel: ItemSelectionModel { onCurrentChanged: (current, previous) => { var item = view.itemAtIndex(current); view.currentItem = item; item.focus = true; } } Rectangle { id: highlight color: "yellow" anchors.fill: view.currentItem ? view.currentItem : null } delegate: FocusScope { implicitHeight: 50 implicitWidth: 50 Keys.onReturnPressed: ti.focus = !ti.focus onFocusChanged: ti.focus = false TextInput { id: ti text: model.display onAccepted: { var nextIndex = view.index((row + 1) % view.model.rowCount, column); view.selectionModel.setCurrentIndex(nextIndex, ItemSelectionModel.Current) } } } } } -
I overlooked the portion of the request to separate the index change from the delegate. The current index can be pulled from the view's
currentRowandcurrentColumnproperties, or from the selection model. Egview.selectionModel.currentIndex.rowandview.selectionModel.currentIndex.column.