Custom QIcon using QIconEngine and transparency

I am trying to implement something like a "composed icon" in Qt.

Purpose: I need to dynamically set the color for only part of the icon.

My idea: Compose this icon with two others. One icon to be painted as desired (possibly ColorizeEffect) and blend it under the second icon, which acts as an overlay layer.

Problem: I tried QIconEngine and implemented the paint method. ColorizeEffect doesn't seem to work (even when I try to crack a temporary QLabel for this - when the force is set to> 0.0, the QIcon thus formed is empty). But this is not the main problem. The fact is that no matter what I do, I get the default color background for this β€œlinked” icon.
Two QToolButtons with QIcons, left icon is simple QIcon, right is my "Composed" icon


Here is a snippet of my code:

class QComposedIconEngine: public QIconEngine { public: QComposedIconEngine(); ~QComposedIconEngine(); virtual void paint ( QPainter * painter, const QRect & rect, QIcon::Mode mode, QIcon::State state ); virtual QIconEngine * clone(void) const; public: QIcon m_qIconA; QIcon m_qIconB; QColor m_qColor; }; 

And here is my paint implementation (...):

 void CLxQComposedIconEngine::paint ( QPainter * painter, const QRect & rect, QIcon::Mode mode, QIcon::State state ) { QBrush brush = painter->background(); QColor color = brush.color(); brush.setColor( Qt::transparent ); painter->setBackground( brush ); painter->eraseRect( rect ); painter->setCompositionMode( QPainter::CompositionMode_SourceOver ); m_qIconA.paint( painter, rect, Qt::AlignCenter, mode, state ); }; 

And this is how I create the Composed icon:

 QComposedIconEngine * qIconEngine = new QComposedIconEngine(); QIcon i1; QIcon i2; i1.addPixmap(...); i2.addPixmap(...); qIconEngine->m_qIconA = i1; qIconEngine->m_qIconB = i2; QIcon i3( qIconEngine ); 

I expect i1 and i3 to look the same. And besides the damn background, it really is. But I need to make it transparent.

(even when I leave my drawing method (...) empty, damn the background exists!)

Does anyone know how to make the background transparent? Thanks.

+7
c ++ user-interface qt qtgui qicon
source share
1 answer

I solved it. The problem was that the overridden paint (...) method was almost always called using the pixmap (...) method, which could also be overridden. If you leave the default implementation, this method will create a new QPixmap , create a QPainter on it and call the paint (...) master. But this is the problem - since the created QPixmap does not contain an alpha channel, it cannot be translucent. Therefore, you need to reimplement the pixmap (...) method as follows:

 QPixmap CLxQComposedIconEngine::pixmap ( const QSize & size, QIcon::Mode mode, QIcon::State state ) { QImage img( size, QImage::Format_ARGB32 ); img.fill(qRgba(0,0,0,0)); QPixmap pix = QPixmap::fromImage(img, Qt::NoFormatConversion ); { QPainter painter ( &pix ); QRect r( QPoint(0.0,0.0), size ); this->paint(&painter, r, mode, state); } return pix; }; 

The key is the first two lines ... Without img.fill (), this will be opaque.

+4
source share

All Articles