Я думал, что смогу удалить любой элемент после того, как он выйдет за пределы сцены с кодом ниже, но это не так. После попытки разных реализаций я думаю, что я должен попробовать другой подход. Некоторые QGraphicsItems на самом деле начинаются за пределами boundingRect, поэтому мне было интересно, есть ли способ удалить и удалить GraphicsItems после того, как они пройдут определенную координатную точку.
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();
}
Проблема в этой строке:
if( !this->sceneRect().intersects(item->boundingRect()))
Это сравнивает прямоугольник сцены, который находится в координатах сцены, с ограничивающим прямоугольником элемента, который находится в локальной системе координат элемента.
Вам нужно преобразовать один из них, чтобы вы сравнивали в одной системе координат.
QRectF itemSceneBoundingRect = item->mapRectToScene(item->boundingRect());
if( !this->sceneRect().intersects(itemSceneBoundingRect)
{
// remove the item.
}
Вы можете сохранить состояние каждого элемента и отслеживать изменения состояния. Вы можете иметь элементы вдоль их состояний в двух QVectors, таких как:
QVector<QGraphicsItem *> items;
QVector<bool> itemIsInBoundingRect; // whether item is boundingrect or not
И обновлять их состояния и отслеживать изменения состояния:
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();
}