LLLit: Изучение и практика программирования

Почему нельзя добавитьItem в QGraphicsScene из QVector‹QGraphicsItem›?

Я хочу отменить или повторить действия в QGraphicsScene, связанном с QGraphicsView: для этого я использую QGraphicsEllipse (для рисования точек при перемещении и нажатии на QGraphicsView) в моем методе mouseMoveEvent, я нажимаю каждый QGraphicsEllipse в QVector<QGraphicsItem>, и когда срабатывает QAction "отмена", программа должна удалить последние эллипсы (определенное количество эллипсов), нарисованные в моем QGraphicsView благодаря моему QGraphicsScene.

Когда я очищаю свой QGraphicsScene и пытаюсь добавить все QGraphicsItems, которые были помещены в мой QVector<QGraphicsItem>, я получаю сообщение об ошибке: мое приложение закрывается!

    if(index < historyIndex.size()){
        for (int i = 0; i < scHistory.size() - historyIndex[index]; i++){
            scene->addItem((QGraphicsItem*)scHistory[i]);
         }
        index++;
    }

    QVector<QGraphicsItem *> scHistory;
23.03.2019

  • Что такое _sceneHistory? Я думаю, вам нужно показать больше контекста. 23.03.2019
  • @drescherjm _sceneHistory — это QVector‹QGraphicsItem *›, который содержит все QGraphicsItem, которые были добавлены в мою сцену. 23.03.2019
  • Вероятно, QGraphicsItem освобождается дважды. QGraphicScene становится владельцем объекта при вызове addItem. QGraphicsScene::clear удаляет и удаляет элементы. Итак, если вы создаете QVector из QGraphicsItem один раз, а код из вашего вопроса (с добавлением и очисткой сцены) вызывается много раз, вы много раз удаляете элементы, что приводит к сбою. Это только мое предположение, потому что вы не предоставили достаточно информации, чтобы воспроизвести вашу проблему. 23.03.2019

Ответы:


1

QGraphicsScene::addItem становится владельцем добавленного элемента, см. документ. Это означает, что теперь он отвечает за уничтожение элемента, что происходит, когда вы очищаете сцену с помощью QGraphicsScene::clear. С этого момента ваш вектор полон оборванных указателей.

Одним из быстрых решений является замена вызова QGraphicsScene::clear ручным удалением элементов через QGraphicsScene::removeItem , который не уничтожает элемент (возвращает право собственности вызывающей стороне). Затем уничтожьте только те элементы, которые на самом деле находятся за пределами сцены, а остальные добавьте обратно. Другой вариант, более эффективный, заключается в удалении только тех элементов, которые вам нужны, с сохранением остальных, так что вы также повышаете производительность, избегая добавления большого количества элементов из истории.

Без полного знания вашего кода вторые варианты могут выглядеть примерно так:

if(_indexHistoryRoam < _indexHistory.size()){
    // Remove only items beyond history
    const int range = _sceneHistory.size() - _indexHistory[_indexHistoryRoam];
    for (int i = range; i < _sceneHistory.size(); i++){
        scene->removeItem((QGraphicsItem*)_sceneHistory[i]);
        delete _sceneHistory[i]; // item must be destroyed to avoid a leak
     }
    _indexHistoryRoam++;
} else { // force removal of all elements
    scene->clear();
}
scene->update();
23.03.2019
Новые материалы

Как развивается смешанно-целочисленное программирование, часть 7
Унифицированная техника раннего завершения для первично-двойственных алгоритмов в смешанно-целочисленном коническом программировании (arXiv) Автор : Ювэнь Чэнь , Кэтрин Нин , Поль Гулар..

Как научить модель Keras распознавать текст переменной длины
Я некоторое время играл с официальным примером Keras image_ocr.py и хочу поделиться своими выводами в этом посте. В официальном примере выполняется только обучение модели, но отсутствует..

Практическая пакетная нормализация
История начинается после использования инициализации He вместе с ELU (или любым вариантом ReLU) может значительно снизить опасность проблем с исчезающими/взрывающимися градиентами в начале..

Поэзия онлайн-кодирования: путешествие пикселей и страсти
В мире, наполненном инновациями, онлайн-обучение программированию становится холстом, на котором обретает форму полотно вашей мечты. Это больше, чем просто создание строк кода; это сродни..

Обработка изображений с помощью Python - размытие и повышение резкости для начинающих
Как применить ядра свертки к цветным изображениям? В этой статье мы обсудим, как применять ядра размытия и повышения резкости к изображениям. Эти базовые ядра составляют основу многих более..

Ограничение скорости в .NET Core 7 Web API
Что такое ограничение скорости? Ограничение скорости — это процесс, используемый для ограничения количества запросов, разрешенных для определенного ресурса в указанном временном окне. .NET..

Стабильная Diffusion 1.0 выдаёт более красивые картинки, чем SD 2.1?! Почему?
Удивительные открытия, которые я сделал недавно. Смотрите в видео: https://youtu.be/PakgD6FewoU Есть одно логичное объяснение — что у вас?