使用QIconEngine和透明度创建自定义QIcon

9
我正在尝试在Qt中实现类似“组合图标”的功能。
目标:我需要动态设置图标部分的颜色。
我的想法:通过两个不同的图标进行组合。其中一个图标将按所需方式进行着色(可以使用ColorizeEffect),然后将其混合在第二个作为覆盖层的图标下面。
问题:我尝试使用QIconEngine并实现其paint方法,但是ColorizeEffect似乎无法工作(即使我尝试使用临时QLabel解决这个问题——当强度设置为>0.0时,由此形成的QIcon为空)。但这不是主要问题。问题是,无论我怎么做,都会得到一些默认颜色的背景,作为这个“组合”图标的底部。
以下是我的代码片段:
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;
};

这是我的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 );
};

以下是我创建“组成”的图标的步骤:

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

我希望i1和i3看起来完全相同,除了可恶的背景颜色之外。但是我需要使其透明。

即使我将我的paint(...)方法留空,可恶的背景仍然存在!有谁知道如何使背景透明吗?谢谢。


QIconEngine的文档中说“请使用QIconEngineV2”。你尝试过了吗? - Vincent Fourmond
当然。没有影响。幸运的是,我解决了这个问题。问题出在QIconEngine从外部被调用的方式上。我将自己编译答案... :-) - GPUquant
1个回答

7
我解决了这个问题。问题在于,重新实现的 paint(...) 方法几乎每次都是通过 pixmap(...) 方法调用的 - 这个方法也可以重新实现。如果你保留默认实现,这个方法会创建一个新的 QPixmap,在其上创建一个 QPainter 并使用该 painter 调用 paint(...)。但这就是问题所在 - 因为创建的 QPixmap 不包含 alpha 通道,所以它不能是半透明的。 因此,你需要像这样重新实现 pixmap(...) 方法:
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;       
};

关键是前两行...没有img.fill()它就不透明。

QPixmap pix(size); pix.fill(Qt::transparent); 这就足够了,你不需要创建 QImage。 - patstew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接