Почему более эффективно удалить QGraphicsItem со сцены перед его уничтожением?

Согласно документации деструктора QGraphicsItem, "более эффективно удалить элемент из QGraphicsScene перед уничтожением элемента."

Почему это? Я не могу представить, как это может иметь значение. И если это имело значение, разве деструктор QGraphicsItem не должен просто вызвать:

if (scene() != NULL)
    scene()->removeItem(this);

Я проверил исходный код, и, похоже, это не так, хотя иногда мне трудно понять исходный код Qt. EDIT: см. комментарии в ответе jdi.


person Anthony    schedule 02.05.2012    source источник


Ответы (1)


Возможно, я интерпретирую документы иначе, чем вы (я не смотрел источник):

QGraphicsItem::~QGraphicsItem () [виртуальный]
Уничтожает объект QGraphicsItem и все его дочерние элементы. Если этот элемент в настоящее время связан со сценой, он будет удален из сцены до того, как будет удален.
Примечание. Более эффективно удалить элемент из QGraphicsScene перед его уничтожением.

Я понимаю, что это означает, что он сначала удалит его со сцены, прежде чем уничтожить, потому что это более эффективно. Но если вы говорите, что источник нигде не указывает, что это происходит, то, похоже, документы будут ложными?

Если бы мне пришлось предположить, почему было бы более эффективно сначала удалить элемент перед его уничтожением (независимо от того, действительно ли API делает это за вас в деструкторе), я бы подумал, что это связано с тем, какие триггеры сцена для переиндексации. Возможно, при удалении элемента, который все еще находится в сцене, каскадное удаление дочерних элементов будет постоянно вызывать переиндексацию сцены. Принимая во внимание, что если вы сначала удалите элемент, он может эффективно извлечь всю иерархию таким образом, что потребуется только одно обновление сцены, а затем может произойти обычное удаление, не влияющее на нее? Может быть даже больше каскадных эффектов других дочерних событий/сигналов, когда они удаляются в сцене.

Бьюсь об заклад, логика «Примечания» заключается в том, чтобы информировать тех, кто будет создавать подкласс QGraphicsItem и перегружать деструктор, чтобы помнить о необходимости сначала удалить со сцены.

person jdi    schedule 02.05.2012
comment
Спасибо за это. Я еще раз проверил исходник, и на самом деле там есть строка, которая проверяет, существует ли сцена, и если да, то вызывает d_ptr->scene->d_func()->removeItemHelper(this);. Я думаю, это должно быть так. Так что, кажется, вы правы, что заметка может просто немного ввести в заблуждение (либо это, либо я дурак). - person Anthony; 03.05.2012
comment
@Anthony: Я собираюсь просто ввести в заблуждение :-). Документы должны быть полезными, и если они сбили вас с толку, то это правильное наблюдение. Хорошая работа по проверке источника для подтверждения. - person jdi; 03.05.2012