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. It's extremely slow to remove all rows from QTableView.
QtWS25 Last Chance

It's extremely slow to remove all rows from QTableView.

Scheduled Pinned Locked Moved Unsolved General and Desktop
qt5.12.1qtableviewqstandarditemremoverow
9 Posts 4 Posters 5.4k Views
  • 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.
  • S Offline
    S Offline
    Sungsong
    wrote on 5 Jul 2019, 08:48 last edited by
    #1

    mainwindow.h

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QDialog>
    #include <QTableView>
    #include <QVBoxLayout>
    #include <QStandardItemModel>
    #include <QPushButton>
    
    
    class MainWindow : public QDialog
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = nullptr);
        QTableView *tableView;
        QVBoxLayout *mainLayout;
        QStandardItemModel *tableModel;
        QHBoxLayout *btLayout;
        QPushButton *deleteAllBt;
        QPushButton *delete10;
    
        ~MainWindow();
    
    
    private:
        int col;
        void retranslateUi();
    
    private slots:
        void delete10Rows();
        void deleteAllRows();
    };
    
    #endif // MAINWINDOW_H
    
    

    mainwindow.cpp

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    
    MainWindow::MainWindow(QWidget *parent) :
        QDialog(parent)
    {
        tableView = new QTableView;
        tableModel = new QStandardItemModel;
        mainLayout = new QVBoxLayout;
        btLayout = new QHBoxLayout;
        delete10 = new QPushButton;
        deleteAllBt = new QPushButton;
    
        tableView->setAttribute(Qt::WA_DeleteOnClose);
        tableView->setSortingEnabled(true);
        tableView->setModel(tableModel);
    
        btLayout->addWidget(delete10);
        btLayout->addWidget(deleteAllBt);
        btLayout->addStretch();
    
        mainLayout->addWidget(tableView);
        mainLayout->addLayout(btLayout);
        setLayout(mainLayout);
    
    
        connect(delete10, SIGNAL(clicked()), this, SLOT(delete10Rows()));
        connect(deleteAllBt, SIGNAL(clicked()), this, SLOT(deleteAllRows()));
    
        retranslateUi();
        resize(QSize(600, 480));
    
        col = 46;  // column count
        for(auto i = 0; i < 10000; i++)
        {
            if (i > 5000)
                col = 70;  //change column count 
            QList<QStandardItem *> items;
            for(auto j = 0; j < col; j++)
            {
                items.append(new QStandardItem(tr("Test %1 x %2").arg(i).arg(j)));
            }
            tableModel->appendRow(items);
        }
    }
    
    MainWindow::~MainWindow()
    {
    
    }
    
    void MainWindow::retranslateUi()
    {
        setWindowTitle(tr("Test"));
        delete10->setText(tr("Delete 10 Rows"));
        deleteAllBt->setText(tr("Delete All"));
    }
    
    void MainWindow::delete10Rows()
    {
        tableModel->removeRows(10, 10);
    }
    
    // it's extremely slow to remove all rows
    void MainWindow::deleteAllRows()
    {
        for(auto row = tableModel->rowCount(); row >= 0;)
        {
            tableModel->removeRow(--row);
        }
    //    tableModel->removeRows(0, tableModel->rowCount());
    }
    
    
    J 1 Reply Last reply 5 Jul 2019, 09:12
    0
    • S Sungsong
      5 Jul 2019, 08:48

      mainwindow.h

      #ifndef MAINWINDOW_H
      #define MAINWINDOW_H
      
      #include <QDialog>
      #include <QTableView>
      #include <QVBoxLayout>
      #include <QStandardItemModel>
      #include <QPushButton>
      
      
      class MainWindow : public QDialog
      {
          Q_OBJECT
      
      public:
          explicit MainWindow(QWidget *parent = nullptr);
          QTableView *tableView;
          QVBoxLayout *mainLayout;
          QStandardItemModel *tableModel;
          QHBoxLayout *btLayout;
          QPushButton *deleteAllBt;
          QPushButton *delete10;
      
          ~MainWindow();
      
      
      private:
          int col;
          void retranslateUi();
      
      private slots:
          void delete10Rows();
          void deleteAllRows();
      };
      
      #endif // MAINWINDOW_H
      
      

      mainwindow.cpp

      #include "mainwindow.h"
      #include "ui_mainwindow.h"
      
      
      MainWindow::MainWindow(QWidget *parent) :
          QDialog(parent)
      {
          tableView = new QTableView;
          tableModel = new QStandardItemModel;
          mainLayout = new QVBoxLayout;
          btLayout = new QHBoxLayout;
          delete10 = new QPushButton;
          deleteAllBt = new QPushButton;
      
          tableView->setAttribute(Qt::WA_DeleteOnClose);
          tableView->setSortingEnabled(true);
          tableView->setModel(tableModel);
      
          btLayout->addWidget(delete10);
          btLayout->addWidget(deleteAllBt);
          btLayout->addStretch();
      
          mainLayout->addWidget(tableView);
          mainLayout->addLayout(btLayout);
          setLayout(mainLayout);
      
      
          connect(delete10, SIGNAL(clicked()), this, SLOT(delete10Rows()));
          connect(deleteAllBt, SIGNAL(clicked()), this, SLOT(deleteAllRows()));
      
          retranslateUi();
          resize(QSize(600, 480));
      
          col = 46;  // column count
          for(auto i = 0; i < 10000; i++)
          {
              if (i > 5000)
                  col = 70;  //change column count 
              QList<QStandardItem *> items;
              for(auto j = 0; j < col; j++)
              {
                  items.append(new QStandardItem(tr("Test %1 x %2").arg(i).arg(j)));
              }
              tableModel->appendRow(items);
          }
      }
      
      MainWindow::~MainWindow()
      {
      
      }
      
      void MainWindow::retranslateUi()
      {
          setWindowTitle(tr("Test"));
          delete10->setText(tr("Delete 10 Rows"));
          deleteAllBt->setText(tr("Delete All"));
      }
      
      void MainWindow::delete10Rows()
      {
          tableModel->removeRows(10, 10);
      }
      
      // it's extremely slow to remove all rows
      void MainWindow::deleteAllRows()
      {
          for(auto row = tableModel->rowCount(); row >= 0;)
          {
              tableModel->removeRow(--row);
          }
      //    tableModel->removeRows(0, tableModel->rowCount());
      }
      
      
      J Offline
      J Offline
      JonB
      wrote on 5 Jul 2019, 09:12 last edited by JonB 7 May 2019, 09:26
      #2

      @Sungsong

      • removeRows() should be faster ---or at least no worse --- than removeRow() one at a time. If it isn't, that's worrying. See e.g. https://www.qtcentre.org/threads/65616-Slow-performance-Removing-huge-amount-of-rows-from-qstandarditemmodel.

      • Make sure beginRemoveRows() gets called once for multiple rows. Verify that your QStandardItemModel does this for you, because I can't actually see that overrides the base QAbstractItemModel::beginRemoveRows(), which does nothing?

      • You have tableView->setSortingEnabled(true);. Try switching that off, at least for the removal, because if the model resorts after each removal it may be slow. Does that make any difference to speed? Even try detaching your view from the model for the duration of the delete and then re-attach at the end? Does that make a significant difference? You need to identify whether its the model or the view which is being "slow" (e.g. view is being updated all the time), and then create solution from there.

      Also, you do not bother to tell us how many rows your "all rows" is? Maybe it's 100,000+? QStandardItemModel is not recommended for "large" numbers of rows (reference: https://www.qtcentre.org/threads/55864-QStandardItemModel-performance-with-high-number-of-elements?p=249783#post249783, and read the other posts if this is your situation).

      S 1 Reply Last reply 5 Jul 2019, 13:20
      5
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on 5 Jul 2019, 09:35 last edited by
        #3

        Hi,

        If you want to empty your model, why not use the clear method ?

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        J VRoninV 2 Replies Last reply 5 Jul 2019, 09:38
        3
        • SGaistS SGaist
          5 Jul 2019, 09:35

          Hi,

          If you want to empty your model, why not use the clear method ?

          J Offline
          J Offline
          JonB
          wrote on 5 Jul 2019, 09:38 last edited by JonB 7 May 2019, 10:19
          #4

          @SGaist
          What's really annoying is that I explicitly searched doc page for a clear() method and got no matches, even though I now see it from your link (I obviously did something wrong) :(

          Of course that does not address if the OP needs to delete, say, all-but-one-row and is finding that too slow, so he still probably wants to address removeRows() speed...

          1 Reply Last reply
          0
          • SGaistS SGaist
            5 Jul 2019, 09:35

            Hi,

            If you want to empty your model, why not use the clear method ?

            VRoninV Offline
            VRoninV Offline
            VRonin
            wrote on 5 Jul 2019, 10:10 last edited by
            #5

            @SGaist said in It's extremely slow to remove all rows from QTableView.:

            If you want to empty your model, why not use the clear method ?

            Clear also removes the headers.
            +1 for using removeRows

            "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

            S 1 Reply Last reply 5 Jul 2019, 13:31
            3
            • J JonB
              5 Jul 2019, 09:12

              @Sungsong

              • removeRows() should be faster ---or at least no worse --- than removeRow() one at a time. If it isn't, that's worrying. See e.g. https://www.qtcentre.org/threads/65616-Slow-performance-Removing-huge-amount-of-rows-from-qstandarditemmodel.

              • Make sure beginRemoveRows() gets called once for multiple rows. Verify that your QStandardItemModel does this for you, because I can't actually see that overrides the base QAbstractItemModel::beginRemoveRows(), which does nothing?

              • You have tableView->setSortingEnabled(true);. Try switching that off, at least for the removal, because if the model resorts after each removal it may be slow. Does that make any difference to speed? Even try detaching your view from the model for the duration of the delete and then re-attach at the end? Does that make a significant difference? You need to identify whether its the model or the view which is being "slow" (e.g. view is being updated all the time), and then create solution from there.

              Also, you do not bother to tell us how many rows your "all rows" is? Maybe it's 100,000+? QStandardItemModel is not recommended for "large" numbers of rows (reference: https://www.qtcentre.org/threads/55864-QStandardItemModel-performance-with-high-number-of-elements?p=249783#post249783, and read the other posts if this is your situation).

              S Offline
              S Offline
              Sungsong
              wrote on 5 Jul 2019, 13:20 last edited by Sungsong 7 May 2019, 13:22
              #6

              @JonB said in It's extremely slow to remove all rows from QTableView.:

              @Sungsong

              • removeRows() should be faster ---or at least no worse --- than removeRow() one at a time. If it isn't, that's worrying. See e.g. https://www.qtcentre.org/threads/65616-Slow-performance-Removing-huge-amount-of-rows-from-qstandarditemmodel.

              • Make sure beginRemoveRows() gets called once for multiple rows. Verify that your QStandardItemModel does this for you, because I can't actually see that overrides the base QAbstractItemModel::beginRemoveRows(), which does nothing?

              • You have tableView->setSortingEnabled(true);. Try switching that off, at least for the removal, because if the model resorts after each removal it may be slow. Does that make any difference to speed? Even try detaching your view from the model for the duration of the delete and then re-attach at the end? Does that make a significant difference? You need to identify whether its the model or the view which is being "slow" (e.g. view is being updated all the time), and then create solution from there.

              Also, you do not bother to tell us how many rows your "all rows" is? Maybe it's 100,000+? QStandardItemModel is not recommended for "large" numbers of rows (reference: https://www.qtcentre.org/threads/55864-QStandardItemModel-performance-with-high-number-of-elements?p=249783#post249783, and read the other posts if this is your situation).

              1. Because I just want to remove selected rows.
              2. Disable sorting doesn't help.

              The key point is: these rows have different column count . If they have same column count, it's fairly fast, even if I removeRow() one by one.

              J 1 Reply Last reply 5 Jul 2019, 13:36
              0
              • VRoninV VRonin
                5 Jul 2019, 10:10

                @SGaist said in It's extremely slow to remove all rows from QTableView.:

                If you want to empty your model, why not use the clear method ?

                Clear also removes the headers.
                +1 for using removeRows

                S Offline
                S Offline
                Sungsong
                wrote on 5 Jul 2019, 13:31 last edited by
                #7

                @VRonin @SGaist
                removeRows() and clear() doesn't help. The key point is: these rows have different column count.

                Another case:
                All rows have same column count.

                1. Remove 10 rows first.
                2. Remove all rows.

                The problem will also happen.

                1 Reply Last reply
                0
                • S Sungsong
                  5 Jul 2019, 13:20

                  @JonB said in It's extremely slow to remove all rows from QTableView.:

                  @Sungsong

                  • removeRows() should be faster ---or at least no worse --- than removeRow() one at a time. If it isn't, that's worrying. See e.g. https://www.qtcentre.org/threads/65616-Slow-performance-Removing-huge-amount-of-rows-from-qstandarditemmodel.

                  • Make sure beginRemoveRows() gets called once for multiple rows. Verify that your QStandardItemModel does this for you, because I can't actually see that overrides the base QAbstractItemModel::beginRemoveRows(), which does nothing?

                  • You have tableView->setSortingEnabled(true);. Try switching that off, at least for the removal, because if the model resorts after each removal it may be slow. Does that make any difference to speed? Even try detaching your view from the model for the duration of the delete and then re-attach at the end? Does that make a significant difference? You need to identify whether its the model or the view which is being "slow" (e.g. view is being updated all the time), and then create solution from there.

                  Also, you do not bother to tell us how many rows your "all rows" is? Maybe it's 100,000+? QStandardItemModel is not recommended for "large" numbers of rows (reference: https://www.qtcentre.org/threads/55864-QStandardItemModel-performance-with-high-number-of-elements?p=249783#post249783, and read the other posts if this is your situation).

                  1. Because I just want to remove selected rows.
                  2. Disable sorting doesn't help.

                  The key point is: these rows have different column count . If they have same column count, it's fairly fast, even if I removeRow() one by one.

                  J Offline
                  J Offline
                  JonB
                  wrote on 5 Jul 2019, 13:36 last edited by
                  #8

                  @Sungsong

                  The key point is: these rows have different column count . If they have same column count, it's fairly fast, even if I removeRow() one by one.

                  Do you think it would have helped us if you had drawn attention to this unusual situation (different column count) when you first pasted in your code with no comment/explanation at all? Or do you think it better we figure this for ourselves?

                  1 Reply Last reply
                  2
                  • S Offline
                    S Offline
                    Sungsong
                    wrote on 5 Jul 2019, 14:30 last edited by
                    #9

                    @JonB
                    I added comments in my code. I think I should explain it clearly. Sorry... but please help.

                    1 Reply Last reply
                    0

                    1/9

                    5 Jul 2019, 08:48

                    • Login

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