Zooming in a QGraphicsScene makes my drawings disappear sometimes

1k views Asked by At

I have a QGraphicsScene where I add a QPixmap composed of 4 images and the borders of each image.

I create a new QPixmap with the total size and then use a QPainter to draw each sub-image in the appropiate place in the bigger pixmap. After one sub-image is done, inmediately draw its borders (this may not be optimal but for now I don't mind).

Once the "final" pixmap is finished, I insert directly to the scene with

scene->addPixmap( total )

Here's the code for the pixmap composition:

QPixmap pixFromCube( PanoramicImages* lim ) const
{
    const QSize img_size = getImageSize( lim );
    const QSize pano_size( img_size.width() * 4, img_size.height() );

    QPixmap toret( pano_size );

    if( !toret.isNull() ) {
        QPainter painter( &toret );
        painter.setRenderHint( QPainter::Antialiasing );
        int x( 0 );
        QPixmap pix = lim->getCamera1Image();
        if( !pix.isNull() ) {
            painter.drawPixmap( 0, 0, pix.width(), pix.height(), pix );
            drawPixBorder( painter, pix.rect() );

        }
        x += img_size.width();

        pix = lim->getCamera2Image();
        if( !pix.isNull() ) {
            painter.drawPixmap( x, 0, pix.width(), pix.height(), pix );
            drawPixBorder( painter, QRectF( x, 0, pix.width(),
                                            pix.height() ) )
            ;

        }
        x += img_size.width();

        pix = lim->getCamera3Image();
        if( !pix.isNull() ) {
            painter.drawPixmap( x, 0, pix.width(), pix.height(), pix );
            drawPixBorder( painter, QRectF( x, 0, pix.width(),
                                            pix.height() ) )
            ;
        }
        x += img_size.width();

        pix = lim->getCamera4Image();
        if( !pix.isNull() ) {
            painter.drawPixmap( x, 0, pix.width(), pix.height(), pix );
            drawPixBorder( painter, QRectF( x, 0, pix.width(),
                                            pix.height() ) )
            ;

        }
    }
    return toret;
}

And

void drawPixBorder( QPainter& painter, const QRectF rect ) const
{
    const QBrush oldBrush = painter.brush();
    const QPen oldPen = painter.pen();

    QColor color( Qt::blue );
    if( timer.isActive() ) {
        color = Qt::green;
    } else {
        color = Qt::red;
    }

    const QBrush brush( color );
    QPen pen( brush, 22 );

    const QPointF points[ 5 ] = {
        rect.topLeft(),
        rect.topRight(),
        rect.bottomRight(),
        rect.bottomLeft(),
        rect.topLeft()
    };
    painter.setBrush( brush );
    painter.setPen( pen );
    painter.drawPolyline( points, sizeof( points ) / sizeof( points[ 0 ] ) );

    painter.setBrush( oldBrush );
    painter.setPen( oldPen );
}

Here's the final pixmap when it's loaded for the first time:

Initial stage

And here after a few zoom-outs:

Zoomed out

As you can see, at the right some of the borders are missing. When zooming back again to the inital position, the borders are displayed. If I use a smaller width for the lines (say, 5), the borders disappear sooner.

I've been reading other questions here and in the Qt Forums and tried some suggestions like:

pen.setCosmetic( true );

or

painter.setRenderHint( QPainter::NonCosmeticDefaultPen, false);

or:

painter.setRenderHint( QPainter::Antialiasing );

setting the pen width directly to 0

pen.setWidth( 0 )

and combinations.

Neither of them prevented the borders to disappear and using a bigger width just delays the problem.

Is there a way to show always the borders regardless of the zoom level?


Thanks to @Robert for his help. As he has stated in his answer, the solution was to draw directly in the scene, instead of doing it in the pixmap and then adding it. For drawing in the scene, I decided to use a QPainterPath:

    int x( 0 );
    QPainterPath rectPath;
    for( unsigned int i( 0 ); i < 4; ++i ) {
        rectPath.addRect( QRectF( x, 0, width, height ) );
        x += width;
    }

    QColor color( Qt::blue );
    if( timer.isActive() ) {
        color = Qt::green;
    } else {
        color = Qt::red;
    }
    scene->addPath( rectPath, QPen( color ) );
1

There are 1 answers

3
Robert On BEST ANSWER

It is because the painter you are using to create the pixmap does not know anything about the transformations/scale of the graphic scene... A possible solutions would be to draw the rectangles within the scene and not directly to the pixmap.