Qt World Summit: Submit your Presentation

QTableView selection is lost when the underlying model changes

  • If a QTableView's model has its row count changed in any way - rows were removed/inserted, the model was reset, the selection, if any, is lost. What I've tried to do is to preserve the selection before the rows count is modified and then restore it after the rows count is updated.

    I've connected to:

    • rowsAboutToBeInserted
    • rowsAboutToBeRemoved
    • modelAboutToBeReset

    when saving the current selection, and to:

    • rowsInserted
    • rowsAboutToBeRemoved
    • modelAboutToBeReset

    ... when restoring the selection if the previously selected model indices still exist.

    The problem is that nothing gets selected when restoring the selection,

    Any suggestions?

  • Moderators

    do you really save the selection as QModelIndexes or just the plain rows as integers?

  • Tried both with saving the QItemSelection and the QModelIndexList which represents the selected indices - doesn't work. I even called selectAll on the view directly after the rows count changed but that didn't help, too.

  • Moderators

    i thought so...

    From the QModelIndex docs:
    Note: Model indexes should be used immediately and then discarded. You should not rely on indexes to remain valid after calling model functions that change the structure of the model or delete items. If you need to keep a model index over time use a QPersistentModelIndex.

    But IMHO you shouldn't restore the selection when the model got reseted. So you should be fine using QPersistentModelIndexes.

  • Currently, the selection model I use is configured to support multiple selection of rows only.
    The QPersistentModelIndex are invalidated as well. So, now I tried saving the row indices as pure integers and recreating the model indices when restoring the selection.

    So, I selected several rows, obtained their indices, recreated the model indices when restoring the selection, and started selecting each row using:
    selectionModel->select( modelIndex, QItemSelectionModel::Rows | QItemSelectionModel::SelectCurrent );

    The effect was that only the last row in the list of previously selected rows got selected. The QItemSelectionModel's documentation states that the flag QItemSelectionModel::Current preserves the current selection, so that using QItemSelectionModel::select along with this flag will result in updating the current selection.

    In addition, keeping the previously selected row indices is not an option, since if rows are inserted above the selected row, the selected row index would not be correct when restoring the selection. The QPersistentModelIndex way was a good option but despite being persistent, it again becomes invalidated.

Log in to reply