Question

I thought I could remove any item after it leaves outside the scene with the code below, but that is not the case. After trying different implementations I think I should try another approach. Some QGraphicsItems actually start outside of the boundingRect so I was wondering if there is a way to remove and delete GraphicsItems after they pass a certain coordinate point.

void Scene::advance()
{
        QList <QGraphicsItem *> itemsToRemove;
        foreach( QGraphicsItem * item, this->items())
        {

            if( !this->sceneRect().intersects(item->boundingRect()))
            {
                // The item is no longer in the scene rect, get ready to delete it
                itemsToRemove.append(item);
            }                

        }

        foreach( QGraphicsItem * item, itemsToRemove )
        {
            this->removeItem(item);
            delete(item);
        }    

        QGraphicsScene::advance();
}
Was it helpful?

Solution

The problem is in this line: -

 if( !this->sceneRect().intersects(item->boundingRect()))

This is comparing the scene's rect, which is in scene coordinates, with the item's bounding rect, which is in the item's local coordinate system.

You need to convert one of them so that you're comparing within the same coordinate system.

 QRectF itemSceneBoundingRect = item->mapRectToScene(item->boundingRect());
 if( !this->sceneRect().intersects(itemSceneBoundingRect)
 {
      // remove the item.
 }

OTHER TIPS

You can save the state of each item and track state changes. You can have the items along their states in two QVectors like:

QVector<QGraphicsItem *> items;
QVector<bool> itemIsInBoundingRect; // whether item is boundingrect or not

And update their states and track state changes:

void Scene::advance()
{
        for(int i=0;i<items.count();i++)
        {

            if(this->sceneRect().intersects(items[i]->boundingRect()))
            {
                // The item is in scene rect
                itemIsInBoundingRect[i] = true;
            }
            else // The item is in not in scene rect
            {
                if(itemIsInBoundingRect[i]) // track state change
                {
                     this->removeItem(items[i]);
                     delete(items[i]);
                     items.remove(i);
                     itemIsInBoundingRect.remove(i);
                }

            }                

        }

        QGraphicsScene::advance();
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top