Проблемы QGraphicsRectItem и QGraphicsScene при смене сцены - PullRequest
2 голосов
/ 29 декабря 2011

я хочу сделать следующее:

У меня есть небольшой графический интерфейс с QGraphicsView. В этом графическом виде я загружаю картинку:

// m_picture is QPixmap
// image is QImage
// m_graphic is QGraphicsScene
// graphicsView is QGraphicsView

m_picture.convertFromImage(image);
m_graphic->addPixmap(m_picture);
ui->graphicsView->setScene(m_graphic);

Это не вызывает никаких проблем, и я всегда могу загрузить новое изображение без проблем. Теперь помимо того, чтобы просто отображать картинки, я хочу дать пользователю возможность рисовать на них прямоугольник («фокусировать» на определенной области). На самом деле пользователь просто вводит координаты в четырех текстовых полях в графическом интерфейсе (x, y, ширина, высота). После предоставления координат пользователь нажимает кнопку, и отображается прямоугольник со следующими координатами. Я сделал это с помощью этого кода:

void tesseract_gui::show_preview_rect()
{
    int x,y,h,w;
    x = ui->numBox_x->value();
    y = ui->numBox_y->value();
    h = ui->numBox_h->value();
    w = ui->numBox_w->value();

    if( rect_initialized )
    {
        m_graphic->removeItem(m_rect);
    }
    else
    {
        rect_initialized = true;
    }
    m_rect->setPen(QPen(Qt::red));
    m_rect->setRect(x,y,h,w);
    m_graphic->addItem(m_rect);
    return;
}

Вызов удалить, потому что я всегда хочу отобразить только один прямоугольник. Теперь, как я уже говорил, это прекрасно работает. Но если пользователь сейчас загружает другое изображение (с вызовами вверху моего поста), программа вылетает, когда я пытаюсь нарисовать новый прямоугольник. я получить ошибку сегментации при вызове

m_rect->setPen(QPen(Qt::red));

Если я позвоню

m_graphic->removeItem(m_rect);

после загрузки новой картинки я получаю

QGraphicsScene :: removeItem: сцена 0x8c04080 элемента (0x0) отличается от этой сцены (0x8c0a8b0)

, а затем происходит сбой с той же ошибкой в ​​setPen.

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

С наилучшими пожеланиями

// редактировать:

Я пытался делать это только с каждым новым прямоугольником, подобным этому:

void tesseract_gui::show_preview_rect()
{
    int x,y,h,w;
    x = ui->numBox_x->value();
    y = ui->numBox_y->value();
    h = ui->numBox_h->value();
    w = ui->numBox_w->value();

    m_graphic->clear();

    m_graphic->addRect(x,y,h,w);
    return;
}

Проблема в том, что при вызове clear () он также очищает само изображение из моего GraphicsView ... так что никакого решения нет

// редактировать:

Как и предполагалось, я избавился от предупреждения вот так:

if( m_rect->scene() != 0 )
{
    m_graphic->removeItem(m_rect);
}

m_rect->setPen(QPen(Qt::red));
m_rect->setRect(x,y,h,w);
m_graphic->addItem(m_rect);

Я знаю, что это не самый лучший способ, но я пробовал и таким образом (у меня не получилось):

Я добавил элемент в конструктор:

m_graphic->addItem(m_rect);

, а затем

m_rect->setPen(QPen(Qt::red));
m_rect->setRect(x,y,h,w);
m_graphic->update();

и я получаю "ту же самую" ошибку, как всегда (программа падает при m_rect-> setPen ()) Таким образом, кажется, что проблема всегда возникает, когда я уже добавил прямоугольник к графике, ТО изменил изображение m_graphic, а затем выполнил любую операцию с m_rect. (На самом деле, я полагаю, что m_graphic становится владельцем m_rect, и это вызывает ошибку сегментации ...?)

1 Ответ

4 голосов
/ 29 декабря 2011

Сообщение QGraphicsScene::removeItem: item 0x8c04080's scene (0x0) is different from this scene (0x8c0a8b0) говорит вам, что m_rect не находится ни в одной сцене во время вызова.Возможно, он удален где-то еще в вашем коде, или у вас есть 2 переменные с одинаковыми именами в иерархии классов.

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

Даже если вы ДЕЙСТВИТЕЛЬНО хотите удалить его перед его изменением, просто проверьте, находится ли он в сцене, вызвав QGraphicsItem::scene().Нет необходимости в переменной проверки инициализации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...