How to remove rows from QStandardItemModel?
-
In the
QTableView
of theQCompleter
I 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.db
those old names fromreverso.db
remains 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
foreach
with:for (int i = tobeRemoved.count() - 1; i >= 0; i--) model->removeRow(tobeRemoved[i].first, tobeRemoved[i].second);
but it doesn't remove. From the
qDebug
output I get:before 184 after 184
so 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
QTableView
of theQCompleter
I 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.db
those old names fromreverso.db
remains 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 thebool
return 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 thebool
return 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 populateitemsToRemove
in 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 populateitemsToRemove
in this reverse order if you prefer.]@JonB, I've replaced the
foreach
with:for (int i = tobeRemoved.count() - 1; i >= 0; i--) model->removeRow(tobeRemoved[i].first, tobeRemoved[i].second);
but it doesn't remove. From the
qDebug
output I get:before 184 after 184
so it actually doesn't remove any row.
-
@JonB, I've replaced the
foreach
with:for (int i = tobeRemoved.count() - 1; i >= 0; i--) model->removeRow(tobeRemoved[i].first, tobeRemoved[i].second);
but it doesn't remove. From the
qDebug
output I get:before 184 after 184
so 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
for
If 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
delete
onQStandardItem
in 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
delete
onQStandardItem
in 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).