I'm trying to implement something like "composed icon" in Qt.
Target: I need to dynamicaly set color just for the portion of icon.
My idea: Compose this icon by two other. One icon that will be coloured as desired (perhaps by ColorizeEffect) and blend it under second icon that acts as overlay layer.
Issue: I tried QIconEngine and implementing its paint method. ColorizeEffect seems not to be working (even when I try the hack with temporary QLabel for that - when strength is set > 0.0, the QIcon formed by that is empty). But that's not the main problem. The thing is, no matter what I do, I get some default coloured background for this "composed" icon.
Here is fragment 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 implementation of paint(...):
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 here is how I create that "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 exactly the same. And besides the damn background it really is. But I need to make it transparent.
(even when I leave my paint(...) method empty, the damn background is there!)
Does anybody know how to make the background transparent? Thanks.
I solved this. The problem was, that the reimplemented paint(...) method is almost every time called via pixmap(...) method - which can be reimplemented too. If you leave default implementation, this method creates new QPixmap, creates QPainter on it and calls paint(...) witch this painter. But that is the problem - since the created QPixmap contains no alpha channel it cannot be semi-transparent. So you need to reimplement pixmap(...) method like this:
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 are the first two rows... Without the img.fill() it would be not transparent.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With