[Solved] QPainter::setOpacity() not always working in QGraphicsScene::drawBackground()
-
Setting the opacity (e.g. to 0.5) on a QPainter before drawing a QPixmap into a QGraphicsScene background is not always working. This is being done in a QGraphicsScene subclass, in an override of the QGraphicsScene::drawBackground() method. The QPixmap is sometimes being drawn with full opacity -- see the apparent refresh artifacts in this animated GIF (3 frames) and the code example. The QPixmap in this example is large: 13536 x 26679 pixels. This is with Qt 4.8.5 on Windows 7.
- http://cadswes2.colorado.edu/~philw/pub/5449/examp1-anim.gif
- http://cadswes2.colorado.edu/~philw/pub/5449/examp1b.png
- http://cadswes2.colorado.edu/~philw/pub/5449/examp1c.png
- http://cadswes2.colorado.edu/~philw/pub/5449/code1.txt
Any ideas about what the problem is, or another way of doing this? Thank you in advance.
@// virtual from QGraphicsScene
void RwGraphicsScene::drawBackground (QPainter* painter,
const QRectF& exposedRect)
{
// INPUT: QPixmap* _scaledBgPixmap// First, call base class method
QGraphicsScene::drawBackground (painter, exposedRect);// Draw the background image, if it is defined.
if (_scaledBgPixmap)
{
const double opacityFactor (0.5);const QRectF bgImgRect (bgImageRect()); if (exposedRect.contains (bgImgRect)) { const QPointF targetTopLeft (bgImgRect.topLeft()); painter->setOpacity (opacityFactor); // <<< PROBLEM <<<<< painter->drawPixmap (targetTopLeft, *_scaledBgPixmap); } else if (exposedRect.intersects (bgImgRect)) { const QRectF irect (exposedRect.intersected (bgImgRect)); const QPointF irectTopLeft (irect.topLeft()); const double pX (std::max (0.0, (irect.left() - bgImgRect.left()))); const double pY (std::max (0.0, (irect.top() - bgImgRect.top()))); const QRectF sourceRect (pX, pY, irect.width(), irect.height()); painter->setOpacity (opacityFactor); // <<< PROBLEM <<<<< painter->drawPixmap (irectTopLeft, *_scaledBgPixmap, sourceRect); } else { // std::cout << " ... NO INTERSECTION." << std::endl; }
}
}
@ -
SOLVED. This refresh artifact (partial transparency ignored when drawing a QPixmap to the provided QPainter in a QGraphicsScene::drawBackground() subclass implementation -- see above) was caused by something about the internal state of that QPixmap. The QPixmap had been created from a QImage constructed with Format_RGB32 (from data read in from a MrSID file, using a GDAL API). Converting that QImage to Format_ARGB32 before creating the QPixmap fixed this refresh artifact problem.