使用 QIconEngine 和透明度自定义 QIcon

Posted

技术标签:

【中文标题】使用 QIconEngine 和透明度自定义 QIcon【英文标题】:Custom QIcon using QIconEngine and transparency 【发布时间】:2014-12-18 08:09:10 【问题描述】:

我正在尝试在 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”。你试过吗? 当然。没有效果。幸运的是我解决了这个问题。这是从外部调用 QIconEngine 的方式。我要自己编译答案... :-) 【参考方案1】:

我解决了这个问题。问题是,重新实现的 paint(...) 方法几乎每次都通过 pixmap(...) 方法调用 - 这也可以重新实现。如果您保留默认实现,此方法会创建新的 QPixmap,在其上创建 QPainter 并调用 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。

以上是关于使用 QIconEngine 和透明度自定义 QIcon的主要内容,如果未能解决你的问题,请参考以下文章

WinForm里的用户自定义控件如何半透明(急急)

自定义不透明度 Plotly 烛台

带有圆角和透明背景的 Android 自定义警报对话框

如何使用 Python 和 GTK 创建具有自定义文本和透明背景的状态图标/系统托盘图标?

UIMarkupTextPrintFormatter 创建具有自定义背景和透明 HTML 内容的 PDF

解决方法调整CRT终端窗口的配色,透明度,标题栏内容,并自定义配色