Как удалить все элементы QGraphicsItem из QGraphicsScene - PullRequest
10 голосов
/ 15 сентября 2011

Я написал производный класс от QGraphicsScene.В какой-то момент мне нужно удалить все предметы со сцены, и я хочу, чтобы предметы были физически уничтожены (вызывается деструктор).Я попробовал следующее:

QList<QGraphicsItem*> all = items();
for (int i = 0; i < all.size(); i++)
{
    QGraphicsItem *gi = all[i];
    removeItem(gi);
    delete gi; // warning at this line
}

Qt Creator выдает предупреждение: предупреждение: C4150: удаление указателя на неполный тип 'QGraphicsItem';нет деструктора под названием

Я не уверен, почему это так.QGraphicsItem имеет виртуальный деструктор, поэтому элементы должны быть удалены из памяти.

Если это не правильный путь, как я могу удалить все QGraphicsItem s из QGraphicsScene?Обратите внимание, что я знаю, когда сцена удаляется, все элементы также будут удалены.Но я хочу удалить предметы со сцены и нарисовать другие предметы.Я хочу, чтобы удаленные элементы были удалены из памяти.

Ответы [ 3 ]

18 голосов
/ 15 сентября 2011

Вы можете удалять и удалять все элементы с помощью QGraphicsScene :: clear () .

10 голосов
/ 15 сентября 2011

Как и jpalecek , указано, что вам не хватает файла заголовка. Вы должны принять его ответ. Я просто собираюсь указать на две потенциальные проблемы:

Прежде всего, вам не нужно звонить QGraphicsScene::removeItem(). QGraphicsItem::~QGraphicsItem() делает это для вас.

Во-вторых. Будьте осторожны, если вы положите какие-либо QGraphicsItem внутрь других. То есть у вас есть предметы, которые являются детьми других предметов. Деструктор QGraphicsItem автоматически удаляет всех его потомков. Поэтому, когда вы просматриваете элементы, возвращенные из QGraphicsScene, вы можете в конечном итоге удалить дочерний элемент, который уже был удален его родителем. Например, скажем, у вас есть 2 элемента, A и B, а B является дочерним элементом для A. Когда вы удаляете A, B удаляется автоматически. И тогда вы попадаете в B и пытаетесь удалить его. БУМ!

Более безопасный способ сделать это - проверить, является ли предмет верхнего уровня, то есть у него нет родителя:

QList<QGraphicsItem*> all = items();
for (int i = 0; i < all.size(); i++)
{
    QGraphicsItem *gi = all[i];
    if(gi->parentItem()==NULL) {
        delete gi;
    }
}
7 голосов
/ 15 сентября 2011

Вы должны

#include <QGraphicsItem>

в этом файле. В противном случае компилятор не знает, что такое QGraphicsItem, что у него есть виртуальный деструктор и т. Д.

...