user1146783
user1146783

Reputation: 21

Crash in Deleting selected items from QTablewidget

I have a QTablewidget with the following settings

tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
tableWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);

I am trying to delete the user selected rows and use the following code. However, it results in a crash when all items are selected and deleted. Is the following approach correct ? Thanks.

tableWidget->setSortingEnabled(false);
QList<QTableWidgetItem *> selectedEntries = tableWidget->selectedItems();
foreach(QTableWidgetItem * currentItem, selectedEntries) 

{       
if (currentItem->row()!=-1) 
                      tableWidget->removeRow(currentItem->row());   

}
tableWidget->setSortingEnabled(true);

Upvotes: 2

Views: 3360

Answers (3)

RebelMoogle
RebelMoogle

Reputation: 1

Here's an approach that uses minimal QT and replaces most of it with C++11 STD / STL code. (if you prefer std to qt like me, but are forced to interop with qt)

// make sure it is sorted descending.
std::set<int, std::greater<int>> selectedRows;
auto itemList = tableWidget->selectedItems();
for (auto& item : itemList)
{
    selectedRows.insert(item->row());
}
for (int row : selectedRows)
{
    tableWidget->removeRow(row);
}

Upvotes: 0

ePirat
ePirat

Reputation: 1087

It seems this happens because removing the row deletes the items associated with the row, so it could be that in subsequent iterations you iterate over items that were already deleted, which results in accessing invalid memory.

A simple alternative is to use the QModelIndexList to get the selected rows and remove them:

QModelIndexList indexes = ui->tableWidget->selectionModel()->selectedRows();
for (QModelIndex index : indexes) {
    ui->tableWidget->removeRow(index.row());

Upvotes: 0

synthesizerpatel
synthesizerpatel

Reputation: 28056

A slightly different flavor of this operation can be found in the Nokia dev forums, the evolved form provided by Ruzik looks like..

 QSet<int> selectedRows; //we use a set to prevent doubles
 QList<QTableWidgetItem*> itemList = tableWidget->selectedItems();
 QTableWidgetItem * item;
 foreach(item, itemList)
 selectedRows.insert(item->row());
 //get a list, and sort it big to small
 QList<int> rows = selectedRows.toList();
 qSort(rows.begin(), rows.end());
 //now actually do the removing:
 foreach(int row, rows)
  tableWidget->removeRow(row);

Upvotes: 4

Related Questions