2014-12-18 24 views
7

Sto tentando di implementare qualcosa come "icona composta" in Qt.QIcon personalizzato con QIconEngine e trasparenza

Target: Ho bisogno di impostare dinamicamente il colore solo per la parte dell'icona.

La mia idea: Scrivi questa icona con altre due. Un'icona che verrà colorata come desiderato (forse da ColorizeEffect) e sfumata sotto la seconda icona che funge da livello di sovrapposizione.

Problema: ho cercato QIconEngine e attuare il suo metodo dipingere. ColorizeEffect sembra non funzionare (anche quando provo l'hack con QLabel temporanea per questo - quando la forza è impostata> 0.0, il QIcon formato da questo è vuoto). Ma non è questo il problema principale. Il fatto è che, indipendentemente da ciò che faccio, ottengo dello sfondo colorato di default per questa icona "composta".
Two QToolButtons with QIcons, left icon is simple QIcon, right is my "Composed" icon


Ecco frammento del mio codice:

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

E qui è la mia applicazione di vernice (...):

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

Ed è qui come creo l'icona "Composto":

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

Mi aspetto che i1 e i3 abbiano esattamente lo stesso aspetto. E oltre a quel dannato sfondo lo è davvero. Ma ho bisogno di renderlo trasparente.

(anche quando lascio la mia pittura (...) metodo vuoto, lo sfondo è maledetta lì!)

Qualcuno sa come fare lo sfondo trasparente? Grazie.

+0

Doc di QIconEngine dice "usa QIconEngineV2". Hai provato? –

+0

Naturalmente. Nessun effetto. Fortunatamente ho risolto questo problema. È nel modo in cui QIconEngine viene chiamato dall'esterno. Ho intenzione di compilare la risposta da solo ... :-) – GPUquant

risposta

4

Ho risolto questo. Il problema era che il metodo paint (...) reimplementato è quasi sempre chiamato tramite il metodo pixmap (...), che può essere anche reimplementato. Se si lascia l'implementazione predefinita, questo metodo crea nuovo QPixmap, crea QPainter su di esso e chiama paint (...) strega questo pittore. Ma questo è il problema - dal momento che la QPixmap creata non contiene alcun canale alfa, non può essere semi-trasparente. Quindi è necessario reimplementare il metodo pixmap (...) in questo modo:

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

La chiave sono le prime due righe ... Senza il img.fill() sarebbe non trasparente.