How to use stylesheet colors in a custom QPushButton
-
Hi,
I want to create a custom style button. This button should have two lines of text with different font styles and alignments. The button should look like the following example:|------------------------------------------------------| | ICON | firstText bold left aligned | | ICON | secondText right aligned | |------------------------------------------------------|
I've created a subclass of QPushButton and wanted to override the paintEvent. The problem is that not all colors defined in the stylesheet are used. (For details please refer to the comments in the code)
How can I draw the text for the differnt states (hover, focus, pressed) in the color stated in the stylesheet?class SettingsButton : public QPushButton { Q_OBJECT public: explicit SettingsButton(QWidget *parent = 0); void setText2(const QString &text1, const QString &text2); QString getText1(); QString getText2(); signals: public slots: protected: virtual void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE { QRect rect1(55,0,356,25); QRect rect2(55,25,356,25); QFont font; // QPushButton::paintEvent(event); //If I use only this function, everything is displayed //as in the normal paintEvent of the base class. //The colors of the stylesheet are used for the normal button text, //but not for my additional text. //Without the next 4 lines, no stylesheet colors are used. //With these 4 lines, only some colors of the stylesheet are used. //The background-colors of the following states are correct: Normal, Focus, Hover //For the pressed state the background-color of the hover state is used. //Text is always displayed in the color of the normal state. QStyleOption opt; opt.init(this); QPainter p(this); style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); QColor color; QPalette palette; palette = this->palette(); color = palette.color(QPalette::Normal, QPalette::ButtonText); //displays the correct stylesheet of the button qDebug() << "Stylesheet " << this->styleSheet(); //Stylesheet //"QPushButton {image: url(:/Resources/icon.svg); image-position: left; padding: 5px 5px; border: 0px; background-color: darkblue; color: yellow;} //QPushButton:focus {image: url(:/Resources/icon.svg); border: 0px; background-color: red; color: green;} //QPushButton:hover {image: url(:/Resources/icon.svg); border: 0px; background-color: blue; color: red;} //QPushButton:pressed {image: url(:/Resources/icon.svg); border: 0px; background-color: yellow; color: black;}" qDebug() << "Color " << color.red() << color.green() << color.blue(); //Color 255 255 0 --> yellow //Display additional text //This text is only displayed in the color of the normal state (yellow) QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing, true); font = painter.font(); painter.setFont(QFont(font.family(), font.pointSize(), QFont::Bold)); painter.drawText(rect1, Qt::AlignLeft|Qt::AlignVCenter, firstText); painter.setFont(QFont(font.family(), font.pointSize(), QFont::Normal)); painter.drawText(rect2, Qt::AlignRight|Qt::AlignVCenter, secondText); } private: QString firstText; QString secondText; };
The *.cpp file:
SettingsButton::SettingsButton(QWidget *parent) : QPushButton(parent) { } void SettingsButton::setText2(const QString &text1, const QString &text2) { firstText = text1; secondText = text2; update(); //Update the button } QString SettingsButton::getText1() { return firstText; } QString SettingsButton::getText2() { return secondText; }
Thanks in advance for your help.
Regards,
Michael -
Thanks for your answer.
To use 4 QLabels could help, I will give it a try.
Is there a posibility to read out the colors and other styles from a button to witch a stylesheet is asigned?QPushButton::setStyleSheet(QString("background-color: red ..."));
To set the styles is very easy. But how can I read back the background-color in hovered state for example?
QPushButton::getStyle(???); -
Hi,
Are you planning to let somebody change the style of that button ?
-
@SGaist
Yes, I want to change the colors für hover, focus, pressed with a style sheet. This would be the prefered solution. If I didn't get it work I catch the mouse events and draw the colors as wanted. Changes are a little bit more complicated and not an easy exchange of the stylesheet. Do you have another idea how to solve this problem?
@VRonin
I tried your proposal with the 4 Labels in a grid. It is the same behaviour. The text color of the label has always the color specified in QLabel { color: blue; ...}. The Pseudo-States :hover, :focus, :pressed are ignored. The background-color of the state :hover is correct. -
Thanks to all for your help.
I didn't get it solved with stylesheets, but I found a solution which works for me:class SettingsButton : public QPushButton { Q_OBJECT public: explicit SettingsButton(QWidget *parent = 0); void setText2(const QString &text1, const QString &text2); QString getText1(); QString getText2(); signals: public slots: protected: virtual void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE { QRect rect1(55,0,356,25); QRect rect2(55,25,356,25); QFont font; QPushButton::paintEvent(event); //To draw everything of a normal QPushButton m_color = QColor(Qt::white); //same as in stylesheet QPushButton (normal) if( QWidget::hasFocus() ) { m_color = QColor(Qt::red); //same as in stylesheet QPushButton:focus } if( QWidget::underMouse() ) { m_color = QColor(Qt::blue); //same as in stylesheet QPushButton:hover } if( QPushButton::isDown() ) { m_color = QColor(Qt::green); //same as in stylesheet QPushButton:pressed } //Display additional text QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing, true); painter.setPen(m_color); font = painter.font(); painter.setFont(QFont(font.family(), font.pointSize(), QFont::Bold)); painter.drawText(rect1, Qt::AlignLeft|Qt::AlignVCenter, firstText); painter.setFont(QFont(font.family(), font.pointSize(), QFont::Normal)); painter.drawText(rect2, Qt::AlignRight|Qt::AlignVCenter, secondText); } private: QString firstText; QString secondText; QColor m_color; };