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?
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
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.
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.
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.
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())
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())
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:
[0,1,2]
), and you start to delete from 0 -> 1 -> 2
, then only row 0 and row 2 will be deleted!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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With