Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QtableView, need to clear selection index after removing a row



  • I have a tableview with data and a remove button. When I selected a row and clicked on the button, the row was removed with no selection in the view. But when I clicked the button again, another row was removed without me selecting anything.

    This is the remove slot function in my main dialog.

    void MyDialog::slotRemoveData()
    {
        QModelIndex index = ui->myTableView->currentIndex();
        m_myModel->removeData(index);
    }
    

    myModel.cpp

    void MyModel::removeData(const QModelIndex &parent)
    {
        if (!parent.isValid())
            return;
    
        int row = parent.row();
    
        beginRemoveRows(QModelIndex(), row, row);
        m_myData.remove(row);
        endRemoveRows();
    }
    

    I think what happen was that the currentIndex was not cleared after the first remove call, so when I called remove again, it removed the new row that took place of the index.

    There's a clearSelection() in the document but it stated that the current index will not be changed. What is the correct way to deselect it after the first remove?



  • you can make the current index invalid after removing the row:

    void MyDialog::slotRemoveData()
    {
        QModelIndex index = ui->myTableView->currentIndex();
        m_myModel->removeData(index);
        setCurrentIndex(QModelIndex()); 
    }
    


  • @lansing
    Purely a guess: would ui->myTableView->setCurrentIndex(QIndex()) work for you?



  • @gde23 @JonB

    Thanks guy this works. I also want to know why it works. What does QModelIndex means when passed into setCurrentIndex()?



  • Don't use currentIndex(). That one record the last item that was "activated", it does not record selected indexes. You should use ui->myTableView->selectionModel()->selectedIndexes() instead



  • @VRonin

    Hi I just tested it, this still requires to set tableView's current index after remove.



  • @VRonin said in QtableView, need to clear selection index after removing a row:

    That one record the last item that was "activated"

    Thanks! I had never understood that was the definition, I don't think the docs tell you that (that I came across?), they just seem to tell you it's the "current" one!



  • This post is deleted!


  • @lansing said in QtableView, need to clear selection index after removing a row:

    What does QModelIndex means when passed into setCurrentIndex()?

    QModelIndex() is the default-constructed one, https://doc.qt.io/qt-5/qmodelindex.html#QModelIndex

    Creates a new empty model index. This type of model index is used to indicate that the position in the model is invalid.

    In your MyModel::removeData() code it would hit your if (!parent.isValid()) return;.

    [BTW: Since you have a QTableView, not a QTreeView, I don't think you're doing yourself/myself any clarity favours by naming your parameter parent here? There is no parentage, plain const QModelIndex &index would not be misleading.]



  • @VRonin This is the code I tested

    QModelIndexList indexList= ui->myTableView->selectionModel()->selectedIndexes();
    
    if (!indexList.isEmpty()){
        m_myModel->removeData(indexList.first());
    }
    

    This still doesn't deselect the index after remove.



  • @JonB

    Those templates were created by Qt Creator, I was just going with them without knowing much.



  • @lansing

    const QModelIndexList indexList= ui->myTableView->selectionModel()->selectedIndexes();
    for(auto& i : indexList)
        m_myModel->removeData(i);
    ui->myTableView->selectionModel()->select(ui->myTableView->selectionModel()->selection(),QItemSelectionModel::Deselect);
    


  • @VRonin

    I use a vector in my model to hold the data, and for some reason this code is removing 3 rows at a time.



  • I solved my last problem with a check on empty indexList and removing only indexList.first().

        const QModelIndexList indexList= ui->myTableView->selectionModel()->selectedIndexes();
    
        if (indexList.isEmpty()){
               return;
            }
    
        m_myModel->removeData(indexList.first());
    
        ui->myTableView->selectionModel()->select(
                    ui->myTableView->selectionModel()->selection(),
                    QItemSelectionModel::Deselect);
    

    Now I come into another problem trying to remove all. In my model I just called vector::clear() to clear my vector whose holding the data.

    void MyModel::clearAll()
    {
        if (!m_myData.isEmpty()) {
            m_myData.clear();
        }
    }
    

    There are two problems, I don't know what signal I should be emitting. And my view doesn't update with the model.

    myDialog.cpp

    void MyDialog::slotRemoveAll()
    {
        m_myModel->clearAll();
    }
    

    After calling this slot, all my data in the model were cleared, but the table grids still remained.



  • @lansing said in QtableView, need to clear selection index after removing a row:

    There are two problems, I don't know what signal I should be emitting. And my view doesn't update with the model.

    I think these are one problem :) When the model signal is right, the view should update. You have deleted all rows, so you need to emit QAbstractItemModel::rowsRemoved(const QModelIndex &parent, int first, int last), or do begin/endRemoveRows(), with the original number of rows. Or, I think you can do QAbstractItemModel::begin/endResetModel().



  • @JonB

    Thank you begin/endResetModel() solved it.


Log in to reply