51

I am trying to delete all rows from a QTableWidget . Here is what I tried.

for ( int i = 0; i < mTestTable->rowCount(); ++i )
{
    mTestTable->removeRow(i);
}

I had two rows in my table. But this just deleted a single row. A reason could be that I did not create the the table with a fixed table size. The Qt Documentation for rowCount() says,

This property holds the number of rows in the table.

By default, for a table constructed without row and column counts, this property contains a value of 0.

So if that is the case, what is the best way to remove all rows from table?

demonplus
  • 5,613
  • 12
  • 49
  • 68
vinayan
  • 1,597
  • 3
  • 19
  • 42
  • The title of your post is a noun phrase, not a question. It should be "How do you," "How does one", "What is the best way," e.g. – CodeLurker Oct 06 '18 at 11:51

13 Answers13

113

Just set the row count to 0 with:

mTestTable->setRowCount(0);

it will delete the QTableWidgetItems automatically, by calling removeRows as you can see in QTableWidget internal model code:

void QTableModel::setRowCount(int rows)
{
    int rc = verticalHeaderItems.count();
    if (rows < 0 || rc == rows)
        return;
    if (rc < rows)
        insertRows(qMax(rc, 0), rows - rc);
    else
        removeRows(qMax(rows, 0), rc - rows);
}
alexisdm
  • 29,448
  • 6
  • 64
  • 99
  • 1
    The reason not to use `mTestTable->clear();` in many cases, is that it will also remove the column and row titles. It also probably resets column and row widths. – CodeLurker Mar 11 '22 at 12:26
  • 1
    Best way to go: Don't use clear(). Use maybe mTestTable->clearContents(). Then mTestTable->setRowCount(0) – lloydyu24 May 17 '22 at 11:06
30

I don't know QTableWidget but your code seems to have a logic flaw. You are forgetting that as you go round the loop you are decreasing the value of mTestTable->rowCount(). After you have removed one row, i will be one and mTestTable->rowCount() will also be one, so your loop stops.

I would do it like this

while (mTestTable->rowCount() > 0)
{
    mTestTable->removeRow(0);
}
john
  • 85,011
  • 4
  • 57
  • 81
  • 5
    this is not really good solution as it can be enormously slow on big data. `removeRow(mTestTable->rowCount()-1)` is expected to be much faster. – sshilovsky May 07 '14 at 09:11
  • 2
    This is a rather bad solution, for `QTableWidget`s with huge number of rows this will take of lot of time. – SexyBeast May 23 '15 at 11:37
14

AFAIK setRowCount(0) removes nothing. Objects are still there, but no more visible.

yourtable->model()->removeRows(0, yourtable->rowCount());
Paul T. Rawkeen
  • 3,994
  • 3
  • 35
  • 51
damkrat
  • 355
  • 3
  • 6
  • 1
    This contradicts the accepted answer. Which one is the correct one? – Alexandro Sánchez Apr 07 '18 at 14:24
  • Try both. In my case with custom models, i've done it this way, as setRowCount didn't clear rows from model. My version of Qt was 4.4.x – damkrat Sep 26 '18 at 07:33
  • 1
    You are not supposed to use a custom model with `QTableWidget`, the internal model, `QTableModel` is private, and not a part of the Qt API, so you can't properly subclass it. And because ` QTableWidget` uses `qobject_cast` before calling every `QTableModel` function without checking that the cast was successful, if your custom model doesn't inherit from `QTableModel`, you are going to break things. Since `QTableWidget::setRowCount` calls `QTableModel::setRowCount` which **does** call `QTableModel::removeRows` which itself deletes the `QTableWidgetItem`. – alexisdm Mar 31 '20 at 02:29
  • QTableModel inherits QAbstractTableModel though, implementing QTableModel in own manner is a feasible option if e.g. some features are needed. My bad, i'm not sure anymore if i've used QTableWidget vs QTableView in first place. – damkrat Apr 01 '20 at 14:25
10
QTableWidget test;
test.clear();
test.setRowCount( 0);
Alex Gurkin
  • 129
  • 1
  • 3
7

The simple way to delete rows is to set the row count to zero. This uses removeRows() internally.

table->setRowCount(0);

You could also clear the content and then remove all rows.

table->clearContents();
table->model()->removeRows(0, table->rowCount());

Both snippets leave the headers untouched!

If you need to get rid of headers, too, you could switch from clearContents() to clear().

Jens A. Koch
  • 39,862
  • 13
  • 113
  • 141
4

In order to prevent an app crash, disconnect all signals from the QTableView.

// Deselects all selected items
ui->tableWidget->clearSelection();

// Disconnect all signals from table widget ! important !
ui->tableWidget->disconnect();

// Remove all items
ui->tableWidget->clearContents();

// Set row count to 0 (remove rows)
ui->tableWidget->setRowCount(0);
1

Look this post : http://forum.qt.io/topic/1715/qtablewidget-how-to-delete-a-row

QList<QTableWidgetItem*> items = table.findItems(.....);
QMap<int, int> rowsMap;
for(int i = 0; i < items.count(); i++{
  rowsMap[items.at(i).row()] = -1; //garbage value
}
QList<int> rowsList = rowsMap.uniqueKeys();
qSort(rowsList);

//Now go through your table and delete rows in descending order as content would shift up and hence cannot do it in ascending order with ease.
for(int i = rowList.count() - 1; i >= 0; i--){
  table.removeRow(rowList.at(i));
}
demonplus
  • 5,613
  • 12
  • 49
  • 68
d.danailov
  • 9,594
  • 4
  • 51
  • 36
1

You can just add empty item model (QStandardItemModel) to your QTableView (myTableView):

itemModel = new QStandardItemModel;
ui->myTableView->setModel(itemModel);
Alex
  • 1,297
  • 1
  • 16
  • 12
1

In python you can just set the rowCount to zero and that'll work!

tableWidget.setRowCount(0)

This code is tested with PySide6. Hope it will work for PyQt5 and PyQt6 too.

0

Your code does not delete last row.

Try this one.

int totalRow = mTestTable->rowCount();
for ( int i = 0; i < totalRow ; ++i )
{
       mTestTable->removeRow(i);
}

In your code, on the first time, rowCount() have value 2 and value of the i is 0, so its delete 1st row,

But on the second time value of i incremented with 1, but rowCount() return the updated row count which is now 1, so, it does not delete the last row.

Hope now you ll be clear.

AB Bolim
  • 1,997
  • 2
  • 23
  • 47
  • this does not seem to work..probably the index keeps changing when a row is deleted.. – vinayan Apr 06 '13 at 07:20
  • @vinayan - Sorry you are wrong. If you consider the total number of row is 2, and on the 1st iteration `rowCount()` = 2, the 1st row is deleted on the index of `(i = 0)` 0th, and on the 2nd iteration `rowCount()` = 1 and index of `(i=1)` 1st so its try to delete on index of 1st but in on 1st index row is shifted to 0th index as 0th row is deleted, So here the code posted by @Vinayan wont work.. – AB Bolim Apr 06 '13 at 10:50
  • you are right about the logic..actually the rowCount() is not giving me the the 2 value as is should since Qt gives rowCount() = 0 for tables created without predefined rows as is in my case..thanks for the answer – vinayan Apr 08 '13 at 14:45
  • 1
    Your code doesn't work, you can't delete the rows by their index in that order, because deleting a row shift the index of all the rows that follow it (i=0 => next row to delete is still at i=0). If you had to use the index, you could delete the row in the reverse order, so that deleting one index doesn't "invalidate" the other indexes (`for ( int i = totalRow-1; i > 0 ; --i )`). – alexisdm Jul 04 '13 at 22:45
0

Removes all items not in the headers from the view. This will also remove all selections. The table dimensions stay the same.

void QTableWidget::clearContents()

Removes all items in the view. This will also remove all selections and headers.

void QTableWidget::clear()
0

This works for me:

for i in reversed(range(self.tableWidget.rowCount())):
    self.tableWidget.removeRow(i)
סטנלי גרונן
  • 2,917
  • 23
  • 46
  • 68
-1
    table->clear();
    table->setRowCount(0);
    table->setColumnCount(0);
    table->horizontalHeader()->reset();
    table->setHorizontalHeaderLabels(hlables);

This Works Great for Me!!

  • `QTableWidget::clear()` and `QTableWidget::setRowCount()` are already mentioned (with explanation) in more than one answer here, the other methods are irrelevant to this question. – Abderrahmene Rayene Mihoub May 29 '23 at 17:17
  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community May 30 '23 at 05:14