[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.

    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.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.