Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

qt

qt4

qstyle

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.

like image 475
Johan Råde Avatar asked Aug 10 '12 11:08

Johan Råde


2 Answers

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));
    }
};
like image 196
alexisdm Avatar answered Nov 02 '22 12:11

alexisdm


What you are trying to do, seems overly complicated. If you just want a red button, why not use the setStyleSheet() method of the QPushButton? It takes a QString, and you can define your button similar to CSS. Here i created you a red button, similar to the XP ui buttons:

QPushButton 
{ 
    background: qlineargradient(x1:0,y1:0,x2:0,y2:1, stop:0 #f4a3a3,stop: 1 #cc1212);
    border-width: 1px; 
    border-color: #d91414; 
    border-style: solid; 
    padding: 5px; 
    padding-left:10px; 
    padding-right:10px; 
    border-radius: 3px; 
    color:#000;
}

QPushButton:hover
{
    border-color: #e36666;
} 

QPushButton:pressed 
{
    background:qlineargradient(x1:0,y1:0,x2:0,y2:1,stop: 0 #de8383, stop: 1 #ad0C0C); 
    border-color: #d91414;
}

Now you just need to pass the code above as a string to your buttons setStyleSheet() method. If you want to create a button widget, what is red by default, then extend the QPushButton class, create a static QString field with the content above, and set the button as stylesheet in the constructor.

More easy to understand examples on stylesheets: Stylesheet Examples

like image 28
Balázs Édes Avatar answered Nov 02 '22 13:11

Balázs Édes