Multiple row selection in QML TableView
-
wrote on 25 Oct 2023, 09:35 last edited by
Hi all,
I have a TableView (using a QAbstractTableModel) in QML with a couple of filters (via QSortFilterProxyModel) which is working nicely. I can select an individual row from the TableView after filtering the model data. I am now trying to implement a multiple select function, whereby holding the Control button will add the clicked row to the existing selection. In reading the TableView QML documentation, it looks like selectionMode property wasn't introduced until Qt6.6 and I'm using Qt6.5.
Is there a way to implement multiple row selection in Qt6.5?
-
Hi all,
I have a TableView (using a QAbstractTableModel) in QML with a couple of filters (via QSortFilterProxyModel) which is working nicely. I can select an individual row from the TableView after filtering the model data. I am now trying to implement a multiple select function, whereby holding the Control button will add the clicked row to the existing selection. In reading the TableView QML documentation, it looks like selectionMode property wasn't introduced until Qt6.6 and I'm using Qt6.5.
Is there a way to implement multiple row selection in Qt6.5?
@jars121 yes, you can use ItemSelectionModel for that.
-
wrote on 25 Oct 2023, 20:40 last edited by
@GrecKo Is that QItemSelectionModel (on the c++ side) or the ItemSelectionModel QML type?
I read through ItemSelectionModel documentation yesterday before posting here, but I really struggled to understand how to actually implement/apply the model/type. I use the ItemSelectionModel (and onSelectedIndexesChanged) for the single row selection functionality, but I don't see how that can be extended to incorporate multiple selections.
The ItemSelectionModel has an overloaded select() method:
void select(QItemSelection selection, SelectionFlags command)
Am I correct in my understanding that I need to establish and manage the selections using a QItemSelection on the c++ side, and then update the TableView using the ItemSelectionModel select() method? I.e. when a row is clicked on, send the associated QModelIndex to c++ where it's added to the QItemSelection object, emit a signal which is received in QML, update the TableView with the select() method?
-
@GrecKo Is that QItemSelectionModel (on the c++ side) or the ItemSelectionModel QML type?
I read through ItemSelectionModel documentation yesterday before posting here, but I really struggled to understand how to actually implement/apply the model/type. I use the ItemSelectionModel (and onSelectedIndexesChanged) for the single row selection functionality, but I don't see how that can be extended to incorporate multiple selections.
The ItemSelectionModel has an overloaded select() method:
void select(QItemSelection selection, SelectionFlags command)
Am I correct in my understanding that I need to establish and manage the selections using a QItemSelection on the c++ side, and then update the TableView using the ItemSelectionModel select() method? I.e. when a row is clicked on, send the associated QModelIndex to c++ where it's added to the QItemSelection object, emit a signal which is received in QML, update the TableView with the select() method?
wrote on 25 Oct 2023, 21:29 last edited byOk I've sorted this :)
For those struggling to make sense of this as I was, here's the general approach I've put together. Note that the documentation around ItemSelectionModel, ItemSelection, etc. is quite lacking, there is a long-standing bug report for this exact issue.
In QML, I implemented basic Keys.onPressed() and Keys.onReleased() handlers to check whether the Control key was pressed or not at the time of row selection.
In my QSortFilterProxyModel class, I implemented a Q_INVOKABLE function which receives a QModelIndex and a bool as follows:
void myProxyModel::selectRow(const QModelIndex &modelIndex, bool controlPressed) { if (!controlPressed) { m_rowSelection.clear(); } m_rowSelection.select(modelIndex, modelIndex); emit rowSelectionChanged(); }
I then have a Connection in QML which handles the rowSelectionChanged() signal and updates the selectionModel for the TableView as follows:
Connections { target: myProxyModelItem onRowSelectionChanged() { myTableView.selectionModel.select(myProxyModelItem.rowSelection, ItemSelectionModel.Rows | ItemSelectionModel.ToggleCurrent) } }
Hopefully this clears up this process or assists those with this same issue!
-
-
Ok I've sorted this :)
For those struggling to make sense of this as I was, here's the general approach I've put together. Note that the documentation around ItemSelectionModel, ItemSelection, etc. is quite lacking, there is a long-standing bug report for this exact issue.
In QML, I implemented basic Keys.onPressed() and Keys.onReleased() handlers to check whether the Control key was pressed or not at the time of row selection.
In my QSortFilterProxyModel class, I implemented a Q_INVOKABLE function which receives a QModelIndex and a bool as follows:
void myProxyModel::selectRow(const QModelIndex &modelIndex, bool controlPressed) { if (!controlPressed) { m_rowSelection.clear(); } m_rowSelection.select(modelIndex, modelIndex); emit rowSelectionChanged(); }
I then have a Connection in QML which handles the rowSelectionChanged() signal and updates the selectionModel for the TableView as follows:
Connections { target: myProxyModelItem onRowSelectionChanged() { myTableView.selectionModel.select(myProxyModelItem.rowSelection, ItemSelectionModel.Rows | ItemSelectionModel.ToggleCurrent) } }
Hopefully this clears up this process or assists those with this same issue!
@jars121 This doesn't have to be put in the model or in c++ you can do everything in QML.
A QML ItemSelectionModel is a QItemSelectionModel.
For multiple selection you can call the
select(QModelIndex index, SelectionFlags command)
function in QML with the Select flag to add stuff to it.EDIT: The issue you linked about ItemSelectionModel is closed, it is now documented. You could argue it lacks example but there's enough. An other argument could be made that the API could be better and easier to work with.
-
@jars121 This doesn't have to be put in the model or in c++ you can do everything in QML.
A QML ItemSelectionModel is a QItemSelectionModel.
For multiple selection you can call the
select(QModelIndex index, SelectionFlags command)
function in QML with the Select flag to add stuff to it.EDIT: The issue you linked about ItemSelectionModel is closed, it is now documented. You could argue it lacks example but there's enough. An other argument could be made that the API could be better and easier to work with.
wrote on 26 Oct 2023, 11:56 last edited by Bob64
1/6