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 5.0k 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 19 Jun 2020, 12:34 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?

    J 1 Reply Last reply 19 Jun 2020, 12:56
    0
    • G Offline
      G Offline
      gde23
      wrote on 19 Jun 2020, 12:52 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 19 Jun 2020, 13:07
      0
      • L lansing
        19 Jun 2020, 12:34

        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?

        J Online
        J Online
        JonB
        wrote on 19 Jun 2020, 12:56 last edited by
        #3

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

        1 Reply Last reply
        0
        • G gde23
          19 Jun 2020, 12:52

          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 19 Jun 2020, 13:07 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()?

          J 1 Reply Last reply 19 Jun 2020, 13:54
          0
          • V Offline
            V Offline
            VRonin
            wrote on 19 Jun 2020, 13:08 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 J 2 Replies Last reply 19 Jun 2020, 13:50
            2
            • V VRonin
              19 Jun 2020, 13:08

              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 19 Jun 2020, 13:50 last edited by
              #6

              @VRonin

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

              J 1 Reply Last reply 19 Jun 2020, 13:52
              0
              • V VRonin
                19 Jun 2020, 13:08

                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

                J Online
                J Online
                JonB
                wrote on 19 Jun 2020, 13:51 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
                  19 Jun 2020, 13:50

                  @VRonin

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

                  J Offline
                  J Offline
                  JoeCFD
                  wrote on 19 Jun 2020, 13:52 last edited by JoeCFD
                  #8
                  This post is deleted!
                  L 1 Reply Last reply 19 Jun 2020, 14:01
                  0
                  • L lansing
                    19 Jun 2020, 13:07

                    @gde23 @JonB

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

                    J Online
                    J Online
                    JonB
                    wrote on 19 Jun 2020, 13:54 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 19 Jun 2020, 14:04
                    0
                    • J JoeCFD
                      19 Jun 2020, 13:52

                      This post is deleted!

                      L Offline
                      L Offline
                      lansing
                      wrote on 19 Jun 2020, 14:01 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.

                      V 1 Reply Last reply 19 Jun 2020, 14:24
                      0
                      • J JonB
                        19 Jun 2020, 13:54

                        @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 19 Jun 2020, 14:04 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
                          19 Jun 2020, 14:01

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

                          V Offline
                          V Offline
                          VRonin
                          wrote on 19 Jun 2020, 14:24 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 19 Jun 2020, 14:49
                          2
                          • V VRonin
                            19 Jun 2020, 14:24

                            @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 19 Jun 2020, 14:49 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 19 Jun 2020, 15:44 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.

                              J 1 Reply Last reply 19 Jun 2020, 16:10
                              0
                              • L lansing
                                19 Jun 2020, 15:44

                                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.

                                J Online
                                J Online
                                JonB
                                wrote on 19 Jun 2020, 16:10 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 19 Jun 2020, 18:28
                                4
                                • J JonB
                                  19 Jun 2020, 16:10

                                  @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 19 Jun 2020, 18:28 last edited by
                                  #16

                                  @JonB

                                  Thank you begin/endResetModel() solved it.

                                  1 Reply Last reply
                                  0

                                  4/16

                                  19 Jun 2020, 13:07

                                  topic:navigator.unread, 12
                                  • Login

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