Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Difficulty displaying icons in widgets



  • Hi

    I create my first style based on QFusionStyle and I'm interested in the QStyle::generatedIconPixmap function.
    Its purpose and capabilities are perfectly described in the documentation.
    This function accepts one of the parameters - QIcon::mode.
    It is also well described in the technical documentation.

    In my style, I'm trying to influence the display of icons in widgets.
    That is why i'm it redefined the generatedIconPixmap function.
    And so if the iconMode parameter takes QIcon::Normal - the icon is fill red.
    if QIcon::Active - the icon is fill green, if QIcon::Disabled - the icon is fill blue.
    Else the icon is fill grey.

    I have a problem - QIcon::Active and QIcon::Disabled modes work correctly. But QIcon::Normal mode does not work!
    I searched for the information in the technical documentation, but did not find anything.
    I searched the internet - I also did not find anything.
    In the end, trying to inherit a style from another style (QWindowsStyle, QWindowsVistaStyle ...) also did not work.
    The icon is not filled in red.
    What do I do wrong, and how can I fix the result?

    QPixmap MyStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *opt) const
    {
        QImage img = pixmap.toImage().convertToFormat(QImage::Format_ARGB32);
        QPainter painter(&img);
        painter.save();
    
        switch (iconMode) {
            case QIcon::Normal:
                painter.fillRect(img.rect(), QColor(Qt::red));
                break;
            case QIcon::Active:
                painter.fillRect(img.rect(), QColor(Qt::green));
                break;
            case QIcon::Disabled:
                painter.fillRect(img.rect(), QColor(Qt::blue));
                break;
            default:
                painter.fillRect(img.rect(), QColor(Qt::gray));
                break;
        }
    
        painter.restore();
        return QPixmap::fromImage(img);
    }
    

    Work program


  • Lifetime Qt Champion

    Hi,

    Might be a silly question, but did you check which state you get for that button ?



  • @Oleg21 said in Difficulty displaying icons in widgets:

    QStyle::generatedIconPixmap

    No, this question is not silly.

    Actually, I did not check the state of the button. Since this does not affect QIcon::Mode in any way.
    If you look at other widgets, you will expect the same result.

    For example QMenu:
    As you can see from the screenshot, the icon is not filling red.

    Main window with menu

    This indicates a common mechanism for processing the icons in QStyle.
    And implements in the function QStyle::generatedIconPixmap for all widgets that display an icon.
    This function does not get Qicon :: Normal mode value.
    I will say more, the window has three icons, and the function is called only two times.
    I guess that QStyle to display icons in QIcon::Normal mode, bypasses QStyle::generatedIconPixmap function.

    I understand that this is a great code optimization, but it's a fake hope.
    I was hoping to process all QIcon::Modes. However, everything turned out to be wrong.
    How to fix this problem?


  • Lifetime Qt Champion

    How are you setting the icon on the button ?



  • @SGaist

    The project consists of three cpp and two header files.
    The code of cpp files is listed below:

    myapp.cpp

    #include "myapp.h"
    
    myApp::myApp(QWidget *parent) : QMainWindow(parent)
    {
        QIcon icns(":/03_Images/simple_icon.png");
    
        QPushButton* btnNormal = new QPushButton(this);
        btnNormal->setText("Normal");
        btnNormal->setIcon(icns);
    
        QPushButton* btnActive = new QPushButton(this);
        btnActive->setText("Active");
        btnActive->setIcon(icns);
    
        QPushButton* btnDisabled = new QPushButton(this);
        btnDisabled->setText("Disabled");
        btnDisabled->setIcon(icns);
        btnDisabled->setEnabled(false);
    
        QHBoxLayout* layout = new QHBoxLayout();
        layout->addWidget(btnNormal);
        layout->addWidget(btnActive);
        layout->addWidget(btnDisabled);
    
        QWidget* centralWidget = new QWidget(this);
        centralWidget->setLayout(layout);
    
        setCentralWidget(centralWidget);
    
        QMenu* menu = new QMenu(this);
               menu->setTitle("Menu");
        QAction* actItem4_1 = menu -> addAction("Normal icon", this, SLOT(repaint()));
                 actItem4_1 ->setIcon(icns);
        QAction* actItem4_2 = menu -> addAction("Active icon", this, SLOT(repaint()));
                 actItem4_2 ->setIcon(icns);
        QAction* actItem4_3 = menu -> addAction("Disabled icon", this, SLOT(repaint()));
                 actItem4_3 ->setIcon(icns);
                 actItem4_3 ->setEnabled(false);
    
        QMenuBar* menuBar = new QMenuBar(this);
        menuBar->addMenu(menu);
    
        setMenuBar(menuBar);
    }
    

    mystyle.cpp

    #include "mystyle.h"
    
    MyStyle::MyStyle() : QProxyStyle(QStyleFactory::create("fusion")){
        setObjectName("MyStyle");
    }
    
    MyStyle::~MyStyle(){
        //
    }
    
    void MyStyle::polish(QPalette& palette){
        palette.setColor(QPalette::Window,          QColor(230, 230, 230));
        palette.setColor(QPalette::WindowText,      QColor(64, 64, 64));
        palette.setColor(QPalette::Base,            QColor(248, 248, 248));
        palette.setColor(QPalette::AlternateBase,   QColor(243, 243, 243));
        palette.setColor(QPalette::Text,            QColor(64, 64, 64));
        palette.setColor(QPalette::ToolTipBase,     QColor(0, 255, 0));
        palette.setColor(QPalette::ToolTipText,     QColor(64, 64, 64));
        palette.setColor(QPalette::Button,          QColor(194, 194, 194));
        palette.setColor(QPalette::ButtonText,      QColor(64, 64, 64));
        palette.setColor(QPalette::BrightText,      QColor(0, 255, 0));
        palette.setColor(QPalette::Highlight,       QColor(86, 86, 86));
        palette.setColor(QPalette::HighlightedText, QColor(191, 191, 191));
    
        palette.setColor(QPalette::Disabled, QPalette::WindowText,      QColor(128, 128, 128));
        palette.setColor(QPalette::Disabled, QPalette::Button,          QColor(214, 214, 214));
        palette.setColor(QPalette::Disabled, QPalette::ButtonText,      QColor(127, 127, 127));
        palette.setColor(QPalette::Disabled, QPalette::Text,            QColor(128, 128, 128));
        palette.setColor(QPalette::Disabled, QPalette::HighlightedText, QColor(64, 128, 0));
    }
    
    QPixmap MyStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *opt) const
    {
        QImage img = pixmap.toImage().convertToFormat(QImage::Format_ARGB32);
        QPainter painter(&img);
        painter.save();
    
        switch (iconMode) {
            case QIcon::Normal:
                qDebug() << "Normal mode";
                painter.fillRect(img.rect(), QColor(Qt::red));
                break;
            case QIcon::Active:
                qDebug() << "Active mode";
                painter.fillRect(img.rect(), QColor(Qt::green));
                break;
            case QIcon::Disabled:
                qDebug() << "Disabled mode";
                painter.fillRect(img.rect(), QColor(Qt::blue));
                break;
            case QIcon::Selected:
                qDebug() << "Selected mode";
                painter.fillRect(img.rect(), QColor(Qt::magenta));
                break;
            default:
                qDebug() << "Other mode (Unknown)";
                painter.fillRect(img.rect(), QColor(Qt::gray));
                break;
        }
    
        painter.restore();
        return QPixmap::fromImage(img);
    }
    

    main.cpp

    #include "myapp.h"
    #include <QApplication>
    #include "mystyle.h"
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        a.setStyle(new MyStyle());
    
        myApp w;
        w.show();
    
        return a.exec();
    }