It's extremely slow to remove all rows from QTableView.
-
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()); }
-
-
removeRows()
should be faster ---or at least no worse --- thanremoveRow()
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 yourQStandardItemModel
does this for you, because I can't actually see that overrides the baseQAbstractItemModel::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). -
-
Hi,
If you want to empty your model, why not use the clear method ?
-
@SGaist
What's really annoying is that I explicitly searched doc page for aclear()
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... -
@JonB said in It's extremely slow to remove all rows from QTableView.:
-
removeRows()
should be faster ---or at least no worse --- thanremoveRow()
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 yourQStandardItemModel
does this for you, because I can't actually see that overrides the baseQAbstractItemModel::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).- Because I just want to remove selected rows.
- 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 IremoveRow()
one by one. -
-
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?