Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I am using QStandardItemModel for my qtableview.

import ui_my_viewlogs
import os
from PyQt4 import QtCore, QtGui

class my_viewlogs(QtGui.QDialog, ui_my_viewlogs.Ui_viewlogs):
    def __init__(self):
        super(my_viewlogs, self).__init__()
        self.setupUi(self)
        self.model = QtGui.QStandardItemModel()
        self.tableView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.header_names = ['abc', 'def', 'ghi', 'kjl', 'mno', 'pqr']
        self.model.setHorizontalHeaderLabels(self.header_names)
        self.tableView.verticalHeader().setVisible(False)
        self.tableView.setShowGrid(False)
        self.selectionModel = self.tableView.selectionModel()
        self.tableView.customContextMenuRequested.connect(self.open_menu)
        self.tableView.setModel(self.model)
        self.tableView.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)

    def open_menu(self, position):
        menu = QtGui.QMenu()
        remove_selected_item_icon = QtGui.QIcon()
        remove_selected_item_icon.addPixmap(QtGui.QPixmap(":/images      /Images/deleteSelected.png"), QtGui.QIcon.Normal, QtGui.QIcon.On)
        remove_selected_item = menu.addAction(remove_selected_item_icon, "Remove selected item(s) ")
        if action == remove_selected_item:           
            model = self.model
            indices = self.tableView.selectionModel().selectedRows() 
            for index in sorted(indices):
                model.removeRow(index.row(), QtCore.QModelIndex()) 

here when I am trying to delete the row selected(i.e. model.removeRow() ) I am getting a error" TypeError: argument 1 of QAbstractItemModel.removeRow() has an invalid type".

I have searched a lot for the correct way of deleting a selected row/rows in qtableview of pyqt. However, I am not able to delete the selected row/rows.

Can you please share a sample code for deleting selected row/rows in qtableview of pyqt?

like image 537
Anuj Bhasin Avatar asked Jun 13 '16 09:06

Anuj Bhasin


People also ask

How do I delete a row in a qtableview?

It's actually a bit simple for a QTableView – Spencer Mar 1 '19 at 22:26 First, the argument to sortedis reverseand not reversed. Second, instead of calling self.table.model().removeRowyou can call self.table.removeRow, which requires only the row index you want to delete. Third, the set of rows can be shortened with a set comprehension. – cbrnr

How to remove selected row from selected row in a Tableview?

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.

How to delete row 0 and Row 2 in SQL?

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 1and row 2as row 0and row 1respectively, thus when you next delete row 1, row 2 (previously) will be deleted as it is now row 1.

How do I remove multiple rows from a table?

If you are removing multiple rows you can run into some complications using the removeRow()call. This operates on the row index, so you need to remove rows from the bottom up to keep the row indices from shifting as you remove them.


4 Answers

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())
like image 58
Kris Kizlyk Avatar answered Oct 16 '22 14:10

Kris Kizlyk


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())                                                               
like image 45
Anuj Bhasin Avatar answered Oct 16 '22 13:10

Anuj Bhasin


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.

like image 38
Doug Fulford Avatar answered Oct 16 '22 13:10

Doug Fulford


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.

like image 28
Tuhin Mitra Avatar answered Oct 16 '22 14:10

Tuhin Mitra