Why does deleting a QTreeWidgetItem* automatically advance iterators associated with the same QTreeWidget? This behavior does not appear to be documented anywhere that I looked. I would expect that after deleting a QTreeWidget* the iterator would be unaffected (other than now pointing to an invalid value). Instead it seems that the QTreeWidget destructor automatically advances all iterators for the QTreeWidget.
Looking briefly into the qt sources, I think this works by having all iterators register themselves with the model when they are created. Then in QTreeItem::~QTreeItem the call to QTreeModel::beginRemoveItems() calls QTreeWidgetItemIteratorPrivate::ensureValidIterator() which advances all of the iterators.
Other than directly inspecting all of the QT sources, how are you supposed to know this happens? Do all QT iterators act this way? I have more experience with STL iterators than with QT and perhaps that is why I found this so unexpected.
The code below demonstrates this behavior:
#include <QTreeWidget>
#include <QDebug>
#include <QApplication>
int main(int argc, char **argv)
{
QApplication a( argc, argv );
QTreeWidget * tw_1 = new QTreeWidget();
QTreeWidget * tw_2 = new QTreeWidget();
for(int i = 1; i <=5; i++)
{
tw_1->addTopLevelItem(new QTreeWidgetItem(QStringList(QString("Item %1").arg(i))));
tw_2->addTopLevelItem(new QTreeWidgetItem(QStringList(QString("Item %1").arg(i))));
}
{
qDebug() << "Elements in Tree Widget 1";
QTreeWidgetItemIterator it(tw_1);
while(*it)
{
qDebug() << "\t" << (*it)->text(0);
++it;
}
//Delete the items while iterating over the tree
QTreeWidgetItemIterator ii(tw_1);
while(*ii)
{
delete *ii;
}
qDebug() << "Elements remaining in Tree Widget 1";
QTreeWidgetItemIterator itt(tw_1);
while(*itt)
{
qDebug() << (*itt)->text(0);
++itt;
}
}
{
qDebug() << "Elements in Tree Widget 2";
QTreeWidgetItemIterator it(tw_2);
while(*it)
{
qDebug() << "\t" << (*it)->text(0);
++it;
}
//Delete the items while iterating over the tree
QTreeWidgetItemIterator ii(tw_2);
while(*ii)
{
delete *ii;
++ii;
}
qDebug() << "Elements remaining in Tree Widget 2";
QTreeWidgetItemIterator itt(tw_2);
while(*itt)
{
qDebug() << (*itt)->text(0);
++itt;
}
}
}
This produces the output:
Elements in Tree Widget 1
"Item 1"
"Item 2"
"Item 3"
"Item 4"
"Item 5"
Elements remaining in Tree Widget 1
Elements in Tree Widget 2
"Item 1"
"Item 2"
"Item 3"
"Item 4"
"Item 5"
Elements remaining in Tree Widget 2
"Item 2"
"Item 4"