0

I use C++, Qt 4.8.7, Visual Studio in order to create GUI-based application. I have to add some checkable buttons, which contain captions with subcripts. I use 3rd party buttons from github, see richtextpushbutton.h and richtextpushbutton.cpp. The default look of the checked QPushButton looks awful (unreadable), I'd like to change its background in the checked state. How can I change the following methods in order to override background color of this HTML-supporting button for the checked state (when isRichText is true and false)? I've met only examples for simple QPushButton descendants (without QTextDocument).

void RichTextPushButton::paintEvent(QPaintEvent *event)
{
   if (isRichText) {
    QStylePainter p(this);

    QRect buttonRect = rect();
    QPoint point;

    QTextDocument richTextLabel;
    richTextLabel.setHtml(htmlText);

    QPixmap richTextPixmap(richTextLabel.size().width(), richTextLabel.size().height());
    richTextPixmap.fill(Qt::transparent);
    QPainter richTextPainter(&richTextPixmap);
    richTextLabel.drawContents(&richTextPainter, richTextPixmap.rect());

    if (!icon().isNull())
        point = QPoint(buttonRect.x() + buttonRect.width() / 2 + iconSize().width() / 2 + 2, buttonRect.y() + buttonRect.height() / 2);
    else
        point = QPoint(buttonRect.x() + buttonRect.width() / 2 - 1, buttonRect.y() + buttonRect.height() / 2);

    buttonRect.translate(point.x() - richTextPixmap.width() / 2, point.y() - richTextPixmap.height() / 2);

    p.drawControl(QStyle::CE_PushButton, getStyleOption());
    p.drawPixmap(buttonRect.left(), buttonRect.top(), richTextPixmap.width(), richTextPixmap.height(),richTextPixmap);
} else
    QPushButton::paintEvent(event);
}

QStyleOptionButton RichTextPushButton::getStyleOption() const
{
QStyleOptionButton opt;
opt.initFrom(this);
opt.features = QStyleOptionButton::None;
if (isFlat())
    opt.features |= QStyleOptionButton::Flat;
if (menu())
    opt.features |= QStyleOptionButton::HasMenu;
if (autoDefault() || isDefault())
    opt.features |= QStyleOptionButton::AutoDefaultButton;
if (isDefault())
    opt.features |= QStyleOptionButton::DefaultButton;
if (isDown() || (menu() && menu()->isVisible()))
    opt.state |= QStyle::State_Sunken;
if (isChecked())
    opt.state |= QStyle::State_On;
if (!isFlat() && !isDown())
    opt.state |= QStyle::State_Raised;
if (!isRichText)
    opt.text = QPushButton::text();
opt.icon = icon();
opt.iconSize = iconSize();
return opt;
}
ilya
  • 1,103
  • 14
  • 36
  • Why can't you simply change the background colour when the [`clicked`](http://doc.qt.io/qt-5/qabstractbutton.html#clicked) or [`toggled`](http://doc.qt.io/qt-5/qabstractbutton.html#toggled) signals are emitted? – G.M. Mar 22 '17 at 10:12

2 Answers2

2

The default look of the checked QPushButton looks awful

That's why Qt introduced stylesheets many years ago. Check this out.

To change the background color of a pushed button simply do:

void MyClass::slotToggleButton(bool enable)
{
    m_pushButton->setStyleSheet(enable ? "background: green;" : "");
}
Massimo Callegari
  • 2,099
  • 1
  • 26
  • 39
  • Thanks, I've used stylesheets, but I didn't know about possibility of the hybrid approach (mixing custom `paintEvent` and `setStyleSheet`). – ilya Mar 22 '17 at 11:28
  • But if I use HTML mode for `RichTextPushButton` (`isRichText == true` ), then font style is ignored. – ilya Mar 22 '17 at 12:06
1

The way to go is to use stylesheets. As you see in getStyleOption() the state QStyle::State_On is set when the button is checked which corresponds to the :on pseudo state. In case of the push button the pseudo state :checked may apply too.

QStyle::State_Off 0x00000008 Used to indicate if the widget is not checked.

QStyle::State_On 0x00000020 Used to indicate if the widget is checked.

So your stylesheet could look like:

RichTextPushButton:checked {
    background-color: red;
}

If your isRichText variable is a dynamic property (QObject::property) you can restrict your stylesheet further:

RichTextPushButton[isRichText="true"]:checked {
    background-color: red;
}
bkausbk
  • 2,740
  • 1
  • 36
  • 52
  • Thanks, I've tried with your stylesheet, but the color is not solid (red is mixed with gray). – ilya Mar 22 '17 at 11:19
  • Adding `border: none;` solved it http://stackoverflow.com/questions/24718722/how-to-style-qpushbuttons-checked-state-to-remove-grey-dots – ilya Mar 22 '17 at 11:25