简体   繁体   中英

QLabel with pixmap: prevent pixmap's color change in disabled state

How can I control the color of its pixmap in disabled label state?

For some bizarre reasons I need to have exactly the same look of the pixmap in active and disabled state (displayed logo).

The pixmap I put on a QLabel with label->setPixmap(pm) is always shown in a different color than the active state when the label is in disabled state.

I struggled with the stylesheet and tried QFrame:disabled{background-color: rgba(..., ..., ..., 255);} but the part of the label which is covered with the pixmap is always a mix with another color, which seems to come from Qt's controlling for the disabled state.


EDIT: It seems, Qt always mixes the pixmap color and the background color in disabled state. But Qt does not mix the colors in active state; then the pixmap color stays opaque. I need to switch off this mixing behavior of the disabled state.

A (not so complicated) way to achieve that, is to draw the pixmap by yourself. Instead of subclassing QLabel and override paintEvent , you can install an event filter in your label and listen for QPaintEvent 's only.

Have the filter:

class Filter : public QObject
{
    Q_OBJECT
public:
    Filter(): QObject(nullptr) {}
    bool eventFilter(QObject *watched, QEvent *event);
};

In its eventFilter method, always return false, but when you draw the pixmap:

#include <QPaintEvent>
#include <QPainter>
#include <QStyle>
bool Filter::eventFilter(QObject *watched, QEvent *event)
{
    if(event->type() == QEvent::Paint)
    {
        QLabel * label = dynamic_cast<QLabel*>(watched);
        QPainter painter(label);

        QPixmap pixmap = label->pixmap()->scaled(label->size());        
        label->style()->drawItemPixmap(&painter, label->rect(), Qt::AlignHCenter | Qt::AlignVCenter, pixmap);
        return true;
    }
    return false;
}

Instantiate and install the filter, something like:

ui->setupUi(this);
Filter * filter = new Filter();
ui->label->installEventFilter(filter);

/* don't forget to call: 

    delete filter;
  
  somewhere later */

In my example code, I scaled the pixmap to fit the label size and centered it both horizontally and vertically, but you can adjust all this, according to your needs.

Moreover, the same filter can be installed to more than one label, since the logic works fine for them all. More on event filtering here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM