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:
And here after a few zoom-outs:
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 ) );
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.