Olumide
Olumide

Reputation: 5829

Styled top-level QPushButton widget does not render properly

I've successfully made a QPushButton the top-level widget/window of an application and am attempting to style the button like so:

#include <QPushButton>
#include <QApplication>

class MyButton : public QPushButton
{
public:
    MyButton() : QPushButton( "Button" )
    {
        setFixedSize( 250 , 65 );
        setStyleSheet( "border-radius: 10px;" ); // style
    }
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MyButton b;
    b.setWindowFlags( Qt::FramelessWindowHint | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint );
    b.setAttribute(Qt::WA_TranslucentBackground); // Fixes opaque BG
    b.show();

    return a.exec();
}

Unfortunately, as the following image shows, the button is no longer rendered properly when the style is applied. I'd appreciate help getting the button to render the style properly.

enter image description here

Edit

Following Kuber Obas answer, I'd appreciate help styling the edges of the widget, i.e. those that are outside the rounded corner, to transparent as shown below

enter image description here

Upvotes: 1

Views: 871

Answers (1)

In most native styles, the border is drawn with the rest of the button using native functionality and its elements cannot be replaced one-by-one. Once you introduce your own styling, the monolithic native styling is gone. So, you'll need to replace all of the functionality provided by the native style, including the border, the background gradient, etc. You will need to tweak it to "match" native style if you so need.

Here, you need to redefine the border completely: at the minimum provide the pen (border:). The radius only makes sense with the pen. You also need to redefine the background, if you care for one, redefine all of the button's state selectors, etc. You start with an unstyled button!

The screenshot below demonstrates it well. On the left you have a Mac-styled native button, on the right you have a button with just its border defined anew. It's obvious that the default state background should also be adjusted to match that of the platform in this case, and some margin needs to be added.

Qt doesn't really re-do modern native styles entirely from scratch, that's why you can't tweak their individual elements. It'd be too much work and a constantly moving target. It used to be done for the old Windows-95/NT style. Starting with the XP style, it was decided to let the platform APIs provide the visual style bitmaps. Similar thing presumably happens on OS X. That's also the reason why you can't use the fancier XP/Aqua/Mac Qt styles outside of their native platform: the relevant native APIs are not present and thus the style is disabled.

screenshot

// https://github.com/KubaO/stackoverflown/tree/master/questions/styledbutton-20642553
#include <QPushButton>
#include <QHBoxLayout>
#include <QApplication>

int main(int argc, char *argv[])
{
   QApplication a{argc, argv};
   QWidget w;
   QHBoxLayout layout{&w};
   QPushButton button1{"Default"};
   button1.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
   layout.addWidget(&button1);
   QPushButton button2{"Styled"};
   button2.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
   button2.setStyleSheet(
      "* { border: 2px solid #8f8f91; border-radius: 12px; background-color: #d02020; }"
      "*:pressed { background-color: #f6f7fa; }");
   layout.addWidget(&button2);
   auto pal = w.palette();
   pal.setBrush(QPalette::Background, Qt::darkBlue);
   w.setPalette(pal);
   w.show();
   return a.exec();
}

Upvotes: 4

Related Questions