Проблема с Qt Undo Framework пример: добавить / удалить элемент

Я использовал пример Qt undo framework в качестве ссылки для реализации этой функции в моем инструменте. Однако, похоже, есть ошибка с тем, как он вызывает деструктор элементов.

Я понимаю, что QGraphicsScene возьмет на себя владение элементами, пока они находятся в сцене. Однако оба объекта undo: AddCommand и RemoveCommand должны стать владельцами этих элементов при их удалении из сцены.

В Примере Qt undo framework только AddCommand пытается удалить объект в своем деструкторе, но не будет делать этого, если элемент все еще находится в сцене.

AddCommand::~AddCommand()
{
    if (!myDiagramItem->scene())
        delete myDiagramItem;
}

В этом случае, если мы удалим элемент из сцены после того, как соответствующий объект AddCommand покинет стек (при использовании ограничения отмены), элемент никогда не будет удален снова, так как деструктор RemoveCommand этого не делает.

1 ответ

  1. Я исправил это, используя флаг в обоих классах AddCommand и RemoveCommand. Он сообщает, когда эти объекты должны нести ответственность за уничтожение элемента. Когда они удаляют элемент из сцены, я устанавливаю этот флаг в true, и я тестирую этот флаг в деструкторе объекта undo перед вызовом деструктора элемента:

    AddCommand::AddCommand(QGraphicsScene *scene, DraftGraphicItem* item, QUndoCommand *parent):
        scene(scene), item(item), QUndoCommand(parent){
        setText("Add item to scene");
    }
    
    AddCommand::~AddCommand(){
        if(isItemOwner)
            delete item;
    }
    
    void AddCommand::undo(){
        Q_ASSERT(item->scene()); 
        scene->removeItem(item);
        isItemOwner = false;
    }
    
    void AddCommand::redo(){
        Q_ASSERT(!item->scene()); 
        scene->addItem(item);
        isItemOwner = true;
    }
    

    и то же самое с RemoveCommand, просто инвертируя методы redo() и undo ().