2
votes

what I want to do is the following:

I have a little GUI with a QGraphicsView. In this graphics View I load a picture:

// 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);

This doesn't cause any problems and I can always load a new image without problems. Now in addition to just display the pictures I want to give the user the ability to draw a rectangle on them ( to "focus" on a specific area ). Actually the user just types in the coordinates in four text boxes on the GUI ( x,y, width,heigth). After providing the coordinates the User presses a button and the rectangle at the following coordinates shall be displayed. I accomplished this with this code:

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;
}

The remove call is because I always want to display just one rectangle. Now as I mentioned this works fine. But if the user now loads another picture ( with the calls at the top of my post ) the program crashes when I try to draw a new rectangle. I get a Segmentation fault at the call of

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

If I call

m_graphic->removeItem(m_rect);

after loading a new picture I get

QGraphicsScene::removeItem: item 0x8c04080's scene (0x0) is different from this scene (0x8c0a8b0)

and then it crashes with the same Error at setPen.

What I don't get is, I don't change the scene. I just add another picture to it ( or overwrite it) . Well any suggestions how I could do this right?

Best Regards

// edit:

I tried to do it just with everytime a new rectangle like this:

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;
}

Problem at this is that with the clear() call it also clears the picture itself from my GraphicsView... so no solution there

// edit:

As suggested I got rid of the Warning like this:

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);

I know it's not the best way but I tried it also this way ( did not work for me ):

I added the item in the constructor:

m_graphic->addItem(m_rect);

and then

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

and I get the "same" error as always ( Program crashes at m_rect->setPen() ) So it seems the problem always occurs when I already added the rectangle to the graphic, THEN changed the image of m_graphic and then did any operation with m_rect. ( Actually I guess m_graphic takes ownership of m_rect and so this causes the segmentation fault ... ? )

1

1 Answers

4
votes

The message QGraphicsScene::removeItem: item 0x8c04080's scene (0x0) is different from this scene (0x8c0a8b0) tells you m_rect is not in any scene at the time you call it. It's probably removed somewhere else in your code or you have 2 variables with the same name in the class hierarchy.

Also, you don't need to remove it from scene to change it. Just change it while it's in the scene. It will get repainted with the new color and geometry in the next paint event.

Even if you REALLY want to remove it before changing it, just check if it's in a scene by calling QGraphicsItem::scene(). There's no need for the init check variable.