How to delete row/rows from a qtableview in pyqt?

This works just fine for me using the reversed().

        indices = self.tag_table.selectionModel().selectedRows()

        # Must delete in reverse order
        for each_row in reversed(sorted(indices)):
            self.tag_table.removeRow(each_row.row())

In C++:

QModelIndexList indices = myTable->selectionModel()->selectedRows();

for (int i=indices.count()-1; i>=0; --i)
{
    QModelIndex index = indices.at(i);
    myTable->removeRow(index.row());
}

You have to go from the bottom to the top of the list or your indexing will be screwed up.


If someone is still looking for an answer after implementing Anuj Bhasin's answer because the above solution will not work in many cases as expected.

Reason:

  • When you delete row index (for example [0,1,2]), and you start to delete from 0 -> 1 -> 2, then only row 0 and row 2 will be deleted!
  • Deleting the First item will shift the remaining rows up, making row 1 and row 2 as row 0 and row 1 respectively, thus when you next delete row 1, row 2 (previously) will be deleted as it is now row 1.

I have a solution to this:

Pass rows you want to delete for example from 5 rows delete [0,3]

def setSel(selected: List[int], table_widget: QTableWidget):
    """
    Select all rows for the given index range
    """
    table_widget.setSelectionMode(QAbstractItemView.MultiSelection)
    for i in selected:
        table_widget.selectRow(i)

then call remove_row_all_table() with table_widget:QTableWidget as parameter

def remove_row_all_table(table_widget):
    """
    Select and Delete rows from table widget
    """
    table_widget: QTableWidget
    selected_rows = table_widget.selectionModel().selectedRows()
    if selected_rows:
        row_indices = []
        for row_index in selected_rows:
            row_indices.append(row_index.row())
        row_indices.sort(key=lambda x: -1 * x)
        print(row_indices)
        for row in row_indices:  # sorted in descending order
            print(f"row count:{table_widget.rowCount()}, deleting index:{row}")
            table_widget.removeRow(row)
    print()

Summary of this answer is: You have to turn on MultiSelection mode and Delete in reverse order, i.e. from higher index to lower index, so that the dependency that I mentioned at the beginning of the answer does not occur.


the method model.removeRow(index.row()) removes the row selected.

model = self.model
    indices = self.tableView.selectionModel().selectedRows() 
    for index in sorted(indices):
        model.removeRow(index.row()) 

in the indices variable we get the selected row, then we delete the row.

For deleting multiple rows in our selection of tableview:

index_list = []                                                          
for model_index in self.tableView.selectionModel().selectedRows():       
    index = QtCore.QPersistentModelIndex(model_index)         
    index_list.append(index)                                             

for index in index_list:                                      
     self.model.removeRow(index.row())