Crash in Deleting selected items from QTablewidget

和自甴很熟 提交于 2021-01-24 07:58:40

问题


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);

回答1:


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);



回答2:


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());



回答3:


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);
}


来源:https://stackoverflow.com/questions/8845069/crash-in-deleting-selected-items-from-qtablewidget

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!