Problem with delete QGraphicsSvgItem.
-
I have bad feeling, that this is maybe stupid question, but I don´t know what is wrong.
This code doesn´t work. I cannot delete the items. Items which I want to delete are from my class:@class graphicsSvgItem : public QGraphicsSvgItem@
code:
@void MainWindow::deleteFigure()
{
QList<QGraphicsItem *> list = scene->items();
for (int i=0;i<list.count();i++) //list of graphics object
{
if (list[i]->flags() & list[i]->ItemIsMovable)
{
scene->removeItem(list[i]);
//delete list[i];
while (!list.isEmpty())
delete list.takeFirst();
//scene->addItem(list[i]);
}}
}@Error:
@Unhandled exception at 0x64dabd58 (QtGuid4.dll) in Chess.exe: 0xC0000005: Access violation reading location 0x00000059.@ -
As you remove items from the list, the list size decreases. When you remove list[0], list[1] becomes the new list[0]. So, in your case, since you're overrunning the bounds of your list because when you increment i, you're really skipping over an item.
Try using a QMutableListIterator to walk the list. Or, at very least, take items from the end of your list, not the beginning.
-
I don´t have time to try it now, but what did you say is true only particularly. If I use only delete list[i] (for clear instead while (!list.isEmpty()) \ delete list.takeFirst();(which is in this cycle maybe even worse idea) which doesn´t work either).
I have for example 5 object in list. 2nd (i=1) is movable so it is delete. Cycle end I increase (i=2) and compare (i < 4 (now I have 4 object)). So I omitted one object, but this is no reason for this kind of mistake. And if I´m at the end of list (we can except that other item aren´t movable) so i=3 compare i<4 and last item is movable so I delete 4th item, end the cycle, increase i (i=4) and compare (i<3) which return fail and cycle end. So you´re right I have this error in code, but this, I thing, shouldn´t cause this kind of error.
I wrote it in hurry (I have to go out) so I hope it is clear (my English is not so good). But I will try what you wrote later.
-
The code is completely wrong. It deletes the complete list if it ever gets into the if branch!
This is the harmful snippet:
@
while (!list.isEmpty())
delete list.takeFirst();
@I just have to agree to mlong:
If you modify the list while iterating over it, a QMutableListIterator is a good approach. As an alternative, iterate from the end, as this does not change the indexes of the yet unvisited items. -
2Volker: You´re right.
I tried these four different approaches. I don´t know what´s wrong:1: There I´m trying to use QMutableListIterator:
@void MainWindow::deleteFigure()
{QList<QGraphicsItem *> list = scene->items();
QMutableListIterator<QGraphicsItem *> i(list);
while (i.hasNext())
{
QGraphicsItem * val = i.next();
if (val->flags() & val->ItemIsMovable)
{
i.remove();
scene->removeItem(val);
delete val;
}
}
}@2:
@void MainWindow::deleteFigure()
{QList<QGraphicsItem *> list = scene->items();
for (int i=0;i<list.count();i++) //list of graphics object
{
if (list[i]->flags() & list[i]->ItemIsMovable)
{
scene->removeItem(list[i]);
value = list[i];
list.removeAt(i);
delete value;//scene->addItem(list[i]); //there I tried if items are really there
//if I comment “delete value;“
}}
}@3: Iteration from end
@void MainWindow::deleteFigure()
{QList<QGraphicsItem *> list = scene->items();
QGraphicsItem * value;
for (int i=list.count();i>0;i--) //list of graphics object
{
if (list[i]->flags() & list[i]->ItemIsMovable)
{
scene->removeItem(list[i]);
value = list[i];
list.removeAt(i);
delete value;
}}
}@
4: There I delete more than I want, but it still doesn´t work
@void MainWindow::deleteFigure()
{QList<QGraphicsItem *> list = scene->items();
while (!list.isEmpty())
delete list.takeFirst();}@
Error is the same everywhere:
@Unhandled exception at 0x64dabd58 (QtGuid4.dll) in Chess.exe: 0xC0000005: Access violation reading location 0x00000059.@
How I create object (maybe there is error? But everything works except delete):
@graphicsSvgItem *svgItem = new graphicsSvgItem("...");
svgItem->setFlags(QGraphicsRectItem::ItemIsSelectable);
svgItem->setFlags(QGraphicsRectItem::ItemIsMovable);
connect(svgItem, SIGNAL(xChanged()),
this, SLOT(figureMoves()));
connect(svgItem, SIGNAL(yChanged()),
this, SLOT(figureMoves()));scene->addItem(svgItem);@
graphicsSvgItem is my class:
@ class graphicsSvgItem : public QGraphicsSvgItem@
-
I probably solved it. I just didn´t think. I had call function which should delete the object from this object itself! Something like:
@void myobject::function()
{
deleteMe();
}@It was little bit more complicated but in principle the same. Now my program fails because another error ( :) ). So I cannot be 100% sure (for now) that error will not appear later. But I think it will not. Function deleteLater () it probably solved it now.
If I were copy whole source code (or best the wrong part) you could help me more… -
In your section 3: Iteration from end above, you have the line:
@
for (int i=list.count();i>0;i--) //list of graphics object
@This will give you a bounds overrun when you try to access list[list.count()].
In that case, you should use:
@
for (int i=list.count()-1; i>=0; i--) //list of graphics object
@