使用QIconEngine和透明度定制QIcon

GPU*_*ant 7 c++ user-interface qt qtgui qicon

我正试图在Qt中实现类似"组合图标"的东西.

目标:我需要动态设置颜色仅适用于图标部分.

我的想法:由另外两个人组成这个图标.一个图标将根据需要进行着色(可能通过ColorizeEffect)并将其混合在充当覆盖层的第二个图标下.

问题:我尝试了QIconEngine并实现了它的paint方法.ColorizeEffect似乎无法正常工作(即使我尝试使用临时QLabel进行破解 - 当强度设置> 0.0时,由此形成的QIcon为空).但这不是主要问题.问题是,无论我做什么,我都会为这个"组合"图标获得一些默认的彩色背景.
带QIcons的两个QToolButtons,左图标是简单的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;
};
Run Code Online (Sandbox Code Playgroud)

这是我对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 );
};
Run Code Online (Sandbox Code Playgroud)

以下是我创建"Composed"图标的方法:

QComposedIconEngine * qIconEngine = new QComposedIconEngine();
QIcon i1;
QIcon i2;
i1.addPixmap(...);
i2.addPixmap(...);
qIconEngine->m_qIconA = i1;
qIconEngine->m_qIconB = i2;
QIcon i3( qIconEngine );
Run Code Online (Sandbox Code Playgroud)

我希望i1和i3看起来完全一样.除了该死的背景,它确实是.但我需要让它变得透明.

(即使我把我的油漆(...)方法留空了,该死的背景就在那里!)

有人知道如何使背景透明吗?谢谢.

GPU*_*ant 5

我解决了 问题是,几乎每次都通过pixmap(...)方法调用重新实现的paint (...)方法-也可以重新实现。如果保留默认实现,则此方法将创建新的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;       
};
Run Code Online (Sandbox Code Playgroud)

关键是前两行...如果没有img.fill(),它将是不透明的。