How to remove rows from QStandardItemModel?
-
In the
QTableViewof theQCompleterI add all object names with tag when a database is attached. When a new database is attached I want to remove the previous database object names before adding news BUT the current approach doesn't work:
So when I attachedreverso.db, I've added all those object names (Table, View, Index, Trigger and Column) and when I attachedquran.dbthose old names fromreverso.dbremains there. Here's the approach I've tried:void QueryView::onDbChanged(QList<QString>& list) { QVector<QString> itemsToRemove = {"Table", "View", "Index", "Trigger", "Column"}; QList<QPair<int, QModelIndex>> tobeRemoved; auto model = editor->getCompleterModel(); qDebug() << "before " << model->rowCount(); for (int i = 0; i < model->rowCount(); i++) { auto index = model->index(i, 1); if(itemsToRemove.contains(model->data(index).toString())) tobeRemoved.append(QPair<int, QModelIndex>(i, index)); } foreach(auto row, tobeRemoved) model->removeRow(row.first, row.second); qDebug() << "after " << model->rowCount(); ... }How to remove those old object names from the
QStandardItemModel, model? -
@JonB, I've replaced the
foreachwith:for (int i = tobeRemoved.count() - 1; i >= 0; i--) model->removeRow(tobeRemoved[i].first, tobeRemoved[i].second);but it doesn't remove. From the
qDebugoutput I get:before 184 after 184so it actually doesn't remove any row.
@Emon-Haque
First of all, you will need that reverse-ordering-removal anyway, so keep that principle.So far as I can see, you have a
QTableView, not aQTreeView. So I assume your model is "flat", not "hierarchical" like a tree? In that case you save upmodel->index(i, 1), whatever that is, and pass it viamodel->removeRow(row.first, row.second)asrow.second. But bool QAbstractItemModel::removeRow(int row, const QModelIndex &parent = QModelIndex())Removes the given row from the child items of the parent specified
What are you doing passing any
parent? Do you just want to omit that parameter? -
In the
QTableViewof theQCompleterI add all object names with tag when a database is attached. When a new database is attached I want to remove the previous database object names before adding news BUT the current approach doesn't work:
So when I attachedreverso.db, I've added all those object names (Table, View, Index, Trigger and Column) and when I attachedquran.dbthose old names fromreverso.dbremains there. Here's the approach I've tried:void QueryView::onDbChanged(QList<QString>& list) { QVector<QString> itemsToRemove = {"Table", "View", "Index", "Trigger", "Column"}; QList<QPair<int, QModelIndex>> tobeRemoved; auto model = editor->getCompleterModel(); qDebug() << "before " << model->rowCount(); for (int i = 0; i < model->rowCount(); i++) { auto index = model->index(i, 1); if(itemsToRemove.contains(model->data(index).toString())) tobeRemoved.append(QPair<int, QModelIndex>(i, index)); } foreach(auto row, tobeRemoved) model->removeRow(row.first, row.second); qDebug() << "after " << model->rowCount(); ... }How to remove those old object names from the
QStandardItemModel, model?@Emon-Haque said in How to remove rows from QStandardItemModel?:
foreach(auto row, tobeRemoved) model->removeRow(row.first, row.second);Your
row.first()holds the original row numbers from the earlierfor (int i ...loop, like0, 1, 2, .... But as soon as you execute the firstmodel->removeRow(row.first /* this is 0 */, row.second);the next row, which was originally1, is now0, so you aren't removing what you think you are (you are leaving some items). Print out theboolreturn result frommodel->removeRow(row.first, row.second);, you should see that the higher numbers returnfalse. -
@Emon-Haque said in How to remove rows from QStandardItemModel?:
foreach(auto row, tobeRemoved) model->removeRow(row.first, row.second);Your
row.first()holds the original row numbers from the earlierfor (int i ...loop, like0, 1, 2, .... But as soon as you execute the firstmodel->removeRow(row.first /* this is 0 */, row.second);the next row, which was originally1, is now0, so you aren't removing what you think you are (you are leaving some items). Print out theboolreturn result frommodel->removeRow(row.first, row.second);, you should see that the higher numbers returnfalse.@JonB, right. It'd be nice if I could pass the model->data() (QVariant) in a remove function.
-
@JonB, right. It'd be nice if I could pass the model->data() (QVariant) in a remove function.
@Emon-Haque
Well you can't! The simplest from here is get rid of yourforeach(auto row, ..., which visits your rows in ascending row number and so gets the numbering wrong during removals, tofor (int i = tobeRemoved.count() - 1; i >= 0; i--), which visits the row numbers in descending order, and should then work correctly? [Or populateitemsToRemovein this reverse order if you prefer.] -
@Emon-Haque
Well you can't! The simplest from here is get rid of yourforeach(auto row, ..., which visits your rows in ascending row number and so gets the numbering wrong during removals, tofor (int i = tobeRemoved.count() - 1; i >= 0; i--), which visits the row numbers in descending order, and should then work correctly? [Or populateitemsToRemovein this reverse order if you prefer.]@JonB, I've replaced the
foreachwith:for (int i = tobeRemoved.count() - 1; i >= 0; i--) model->removeRow(tobeRemoved[i].first, tobeRemoved[i].second);but it doesn't remove. From the
qDebugoutput I get:before 184 after 184so it actually doesn't remove any row.
-
@JonB, I've replaced the
foreachwith:for (int i = tobeRemoved.count() - 1; i >= 0; i--) model->removeRow(tobeRemoved[i].first, tobeRemoved[i].second);but it doesn't remove. From the
qDebugoutput I get:before 184 after 184so it actually doesn't remove any row.
@Emon-Haque
First of all, you will need that reverse-ordering-removal anyway, so keep that principle.So far as I can see, you have a
QTableView, not aQTreeView. So I assume your model is "flat", not "hierarchical" like a tree? In that case you save upmodel->index(i, 1), whatever that is, and pass it viamodel->removeRow(row.first, row.second)asrow.second. But bool QAbstractItemModel::removeRow(int row, const QModelIndex &parent = QModelIndex())Removes the given row from the child items of the parent specified
What are you doing passing any
parent? Do you just want to omit that parameter? -
@Emon-Haque
First of all, you will need that reverse-ordering-removal anyway, so keep that principle.So far as I can see, you have a
QTableView, not aQTreeView. So I assume your model is "flat", not "hierarchical" like a tree? In that case you save upmodel->index(i, 1), whatever that is, and pass it viamodel->removeRow(row.first, row.second)asrow.second. But bool QAbstractItemModel::removeRow(int row, const QModelIndex &parent = QModelIndex())Removes the given row from the child items of the parent specified
What are you doing passing any
parent? Do you just want to omit that parameter?@JonB, in the second
forIf I domodel->removeRow(tobeRemoved[i].second.row())it works.
Thanks. -
@Emon-Haque
First of all, you will need that reverse-ordering-removal anyway, so keep that principle.So far as I can see, you have a
QTableView, not aQTreeView. So I assume your model is "flat", not "hierarchical" like a tree? In that case you save upmodel->index(i, 1), whatever that is, and pass it viamodel->removeRow(row.first, row.second)asrow.second. But bool QAbstractItemModel::removeRow(int row, const QModelIndex &parent = QModelIndex())Removes the given row from the child items of the parent specified
What are you doing passing any
parent? Do you just want to omit that parameter?@JonB, one more thing, hope you wouldn't mind. Do I have to call
deleteonQStandardItemin each column of those rows I'm removing or the Qt framework takes care of that automatically? -
@JonB, one more thing, hope you wouldn't mind. Do I have to call
deleteonQStandardItemin each column of those rows I'm removing or the Qt framework takes care of that automatically?@Emon-Haque
No, the model took ownership of the items when you added them and is responsible for deleting them when you remove them from the model (viaremoveRow(), but not if you usedtakeRow(), see https://www.qtcentre.org/threads/63505-removeRow-or-takeRow-in-QStandardItemModel).