How to render a red push button using QStyle.drawControl()?

Johan Råde picture Johan Råde · Aug 10, 2012 · Viewed 11.3k times · Source

With the following code I tried to render a red push button using QStyle.drawControl():

#include <QtCore/QtCore>
#include <QtGui/QtGui>

class Widget : public QWidget
{
    virtual void paintEvent(QPaintEvent* event)
    {
        QStyleOptionButton opt;
        opt.palette = QPalette(Qt::red);
        opt.state = QStyle::State_Active | QStyle::State_Enabled;
        opt.rect = QRect(50, 25, 100, 50);
        QPainter painter(this);
        style()->drawControl(QStyle::CE_PushButton, &opt, &painter);
    }
};

int main(int argc, char** argv)
{
    QApplication app(argc, argv);
    Widget w;
    w.resize(200, 100);
    w.show();
    return app.exec();
}

However I get the following result:

enter image description here

How do I render a red push button using QStyle.drawControl()?

I'm using Qt 4.8.1 and Visal Studio 2010 on Windows XP.

Answer

alexisdm picture alexisdm · Aug 11, 2012

The buttons are drawn by the native style engine, so the palette might not be used at all (see that question from the FAQ).

You can use an actual button with a stylesheet that you pass as the last parameter to the own button's style drawControl function.

class Widget : public QWidget
{
  // To allow the automatic deletion without parenting it
  QScopedPointer<QPushButton> button;
public:
    Widget() : button(new QPushButton) {
      button->setStyleSheet("background-color: red");
    }
    virtual void paintEvent(QPaintEvent* event)
    {
        QStyleOptionButton opt;
        opt.state = QStyle::State_Active | QStyle::State_Enabled;
        opt.rect = QRect(50, 25, 100, 50);
        QPainter painter(this);
        button->style()->drawControl(QStyle::CE_PushButton, &opt, &painter, 
                                     button.data());
    }
};

But you will loose the native style, so you'll have to fake it (bali182's answer might be useful for that part).

Or you can use the same button with colorize effect and call its render() function to paint it:

Colorized Button

class Widget : public QWidget {
    QScopedPointer<QPushButton> button;
public:
    Widget() : button(new QPushButton) {
        QGraphicsColorizeEffect *effect = new QGraphicsColorizeEffect(button.data());
        effect->setColor(Qt::red);
        button->setGraphicsEffect(effect);
    }
    virtual void paintEvent(QPaintEvent* event) {
        button->setFixedSize(100, 50);
        button->render(this, QPoint(50, 25));
    }
};