Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QtableView, need to clear selection index after removing a row
Forum Updated to NodeBB v4.3 + New Features

QtableView, need to clear selection index after removing a row

Scheduled Pinned Locked Moved Unsolved General and Desktop
16 Posts 5 Posters 4.8k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • L Offline
    L Offline
    lansing
    wrote on last edited by
    #1

    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?

    JonBJ 1 Reply Last reply
    0
    • gde23G Offline
      gde23G Offline
      gde23
      wrote on last edited by
      #2

      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()); 
      }
      
      L 1 Reply Last reply
      0
      • L lansing

        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?

        JonBJ Offline
        JonBJ Offline
        JonB
        wrote on last edited by
        #3

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

        1 Reply Last reply
        0
        • gde23G gde23

          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()); 
          }
          
          L Offline
          L Offline
          lansing
          wrote on last edited by
          #4

          @gde23 @JonB

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

          JonBJ 1 Reply Last reply
          0
          • VRoninV Offline
            VRoninV Offline
            VRonin
            wrote on last edited by VRonin
            #5

            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

            "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
            ~Napoleon Bonaparte

            On a crusade to banish setIndexWidget() from the holy land of Qt

            L JonBJ 2 Replies Last reply
            2
            • VRoninV VRonin

              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

              L Offline
              L Offline
              lansing
              wrote on last edited by
              #6

              @VRonin

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

              JoeCFDJ 1 Reply Last reply
              0
              • VRoninV VRonin

                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

                JonBJ Offline
                JonBJ Offline
                JonB
                wrote on last edited by
                #7

                @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!

                1 Reply Last reply
                0
                • L lansing

                  @VRonin

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

                  JoeCFDJ Offline
                  JoeCFDJ Offline
                  JoeCFD
                  wrote on last edited by JoeCFD
                  #8
                  This post is deleted!
                  L 1 Reply Last reply
                  0
                  • L lansing

                    @gde23 @JonB

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

                    JonBJ Offline
                    JonBJ Offline
                    JonB
                    wrote on last edited by JonB
                    #9

                    @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.]

                    L 1 Reply Last reply
                    0
                    • JoeCFDJ JoeCFD

                      This post is deleted!

                      L Offline
                      L Offline
                      lansing
                      wrote on last edited by
                      #10

                      @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.

                      VRoninV 1 Reply Last reply
                      0
                      • JonBJ JonB

                        @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.]

                        L Offline
                        L Offline
                        lansing
                        wrote on last edited by
                        #11

                        @JonB

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

                        1 Reply Last reply
                        0
                        • L lansing

                          @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.

                          VRoninV Offline
                          VRoninV Offline
                          VRonin
                          wrote on last edited by VRonin
                          #12

                          @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);
                          

                          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                          ~Napoleon Bonaparte

                          On a crusade to banish setIndexWidget() from the holy land of Qt

                          L 1 Reply Last reply
                          2
                          • VRoninV VRonin

                            @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);
                            
                            L Offline
                            L Offline
                            lansing
                            wrote on last edited by
                            #13

                            @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.

                            1 Reply Last reply
                            0
                            • L Offline
                              L Offline
                              lansing
                              wrote on last edited by
                              #14

                              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.

                              JonBJ 1 Reply Last reply
                              0
                              • L lansing

                                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.

                                JonBJ Offline
                                JonBJ Offline
                                JonB
                                wrote on last edited by JonB
                                #15

                                @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().

                                L 1 Reply Last reply
                                4
                                • JonBJ JonB

                                  @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().

                                  L Offline
                                  L Offline
                                  lansing
                                  wrote on last edited by
                                  #16

                                  @JonB

                                  Thank you begin/endResetModel() solved it.

                                  1 Reply Last reply
                                  0

                                  • Login

                                  • Login or register to search.
                                  • First post
                                    Last post
                                  0
                                  • Categories
                                  • Recent
                                  • Tags
                                  • Popular
                                  • Users
                                  • Groups
                                  • Search
                                  • Get Qt Extensions
                                  • Unsolved