Пользовательский QIcon с использованием QIconEngine и прозрачности

Я пытаюсь реализовать что-то вроде "составленного значка" в Qt.

цель: мне нужно dynamicaly установить цвет только для части значка.

мои мысли: создать этот значок двумя другими. Один значок, который будет окрашен по желанию (возможно, ColorizeEffect) и смешать его под вторым значком, который действует как слой наложения.

вопрос: пробовал QIconEngine и реализуя свой краски метод. ColorizeEffect, похоже, не работает (даже когда я пытаюсь взломать временную QLabel для этого - когда сила установлена > 0.0, QIcon, сформированный этим, пуст). Но это не главная проблема. Дело в том, что независимо от того, что я делаю, я получаю цветной фон по умолчанию для этого "составленного" значка.
Two QToolButtons with QIcons, left icon is simple QIcon, right is my "Composed" icon


вот фрагмент моего кода:

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;
};

и вот моя реализация краска.(..):

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 будут выглядеть точно так же. И, кроме проклятого фона, это действительно так. Но мне нужно сделать это прозрачным.

(даже когда я оставляю мою краску(...) метод пустой, проклятый фон есть!)

кто-нибудь знает, как сделать фон прозрачным? Спасибо.

1 ответов


Я решил эту. Проблема была в том, что перекрываем краски(...) метод почти каждый раз вызывается через растровое изображение(...) способ - который тоже может быть переопределен. Если оставить реализацию по умолчанию, этот метод создает new QPixmap создает рисовальщика QPainter на нее и звонит краски(...) ведьма этого художника. Но в этом проблема - поскольку созданный QPixmap не содержит альфа-канала, он не может быть полупрозрачным. Так вы необходимо переопределить 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 () Это было бы непрозрачно.