Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Palette and Style Sheet, applied separately, both are producing inconsistent results. Why?



  • Hi! I am trying to design a UI for scientific equipment. My requirements are:

    • Different layers of background colour so user can distinguish between different sets of widgets.
    • Different colours of the push button based on the current state of software.
    • The UI should be resizable so people working on it in a lab can enlarge it and see it from a distance while doing their experiments.

    I made a test UI which looks like this in Qt Designer:

    Qt_Designer_Layout.PNG

    I first tried to change the palette to get different colours. But it is highly inconsistant:

    Palette.PNG

    When I apply this palette to my UI, this is what I get:

    Palette_MyLayout.PNG

    To overcome this problem I created style sheets. But when I apply style sheets to my ui any button that has a spacer within it's layout is shrunk to it's minimum width. This is what my UI looks like with style sheet applied:

    With_StyleSheet_3_modified.png

    The code that I used for my push button in my Style sheet is:

    QPushButton[flat = "false"]
    {
      border: 1px solid rgb(40, 40, 255);
      border-radius: 1px;
      background-color: rgb(40, 40, 255);
      color: rgb(255, 255, 255);
      font-style: normal;
    }
    
    QPushButton[flat = "true"]
    {
      border: none;
      background-color: none;
      color: rgb(230,230,230);
    }
    
    QPushButton:pressed, QPushButton:checked
    {
      background-color: rgb(180, 180, 255);
      color: rgb(20, 20, 255);
    }
    
    QPushButton:disabled[flat = "false"]
    {
      border-color: rgb(190, 190, 190);
      background-color: rgb(190, 190, 190);
      color: rgb(120,120,120);
    }
    
    QPushButton:disabled[flat = "true"]
    {
      color: rgb(120,120,120);
    }
    
    • How can I just change the background colour and text colours of Frames and Push Buttons without affecting any other properties of any of the widgets?

    • When I apply a style sheet from my QSS file the Fonts are reverted back to the default value. I know I can hard code font in my QSS file but since my UI is resizing, which means the fonts are changing, and so I cannot hardcode a single font size in my QSS file. Is there any way I can implement in my QSS file that it ignores setting the font completely?

    • Most Important: Why is the Palette unable to set the background of Push Buttons? It clearly has access to it since it can easily change it's text colour.



  • Ah, I'd like to answer the most important question first. :)
    It is already in the doc:

    The current style, which is used to render the content of all standard Qt widgets, is free to choose colors and brushes from the widget palette, or in some cases, to ignore the palette (partially, or completely). In particular, certain styles like GTK style, Mac style, and Windows Vista style, depend on third party APIs to render the content of widgets, and these styles typically do not follow the palette. Because of this, assigning roles to a widget's palette is not guaranteed to change the appearance of the widget. Instead, you may choose to apply a styleSheet.

    Talking about the QPushButton, the default windows style will use windows theme data to draw the background, so it won't read the palette color at all. But for the text, it don't, so the palette color will be used.

    Now going to the second one.
    QSS won't set your font if you haven't written font-related properties, so I think removing "font-style: normal" should be ok?

    And the first one...No, it is impossible to change QPushButton's background color but keep all the other properties in your current style.
    I have two options for you:

    1. Use fusion style instead, it doesn't look like native, but it respects the palette more.
    2. Improve your stylesheet to realize what you want, for example, I think what you need here is some padding, so try to add "padding: 4px;" to your QPushButton's stylesheet.


  • @Bonnie Thanks! It is a very helpful answer :)
    You mentioned that QSS won't set your font if you haven't written font-related properties, but it is changing the font for me and in a weird way. I created two new QSS file and I am changing only the background of my QFrames depending on if a checkbox named "Dark Background" in my UI is checked or not. If it is checked I load a file named Dark.qss and if it is unchecked I load a file named Light.qss. The codes in these two files are (Level is a dynamic property added by me in below two files):

    /* Light.qss file */
    QFrame[Level = "One"]{background-color: rgb(230,230,230);}
    QFrame[Level = "Two"]{background-color: rgb(220,220,220);}
    QFrame[Level = "Three"]{background-color: rgb(210,210,210);}
    QFrame[Level = "Four"]{background-color: rgb(200,200,200);}
    
    /* Dark.qss file */
    QFrame[Level = "One"]{background-color: rgb(60,60,60);}
    QFrame[Level = "Two"]{background-color: rgb(50,50,50);}
    QFrame[Level = "Three"]{background-color: rgb(40,40,40);}
    QFrame[Level = "Four"]{background-color: rgb(30,30,30);}
    

    When my UI is launched no QSS file is loaded. To make the change in font apparent I applied Segoe Print 12point font to my QMainWindow class in QT Designer, it looks like this:

    New_1.PNG

    When I click on "Dark Background" checkbox on top it gets checked and the QSS file named Dark.qss is applied and the font doesn't change. It looks like this:

    New_2.PNG

    Now, when I click on "Dark Background" checkbox again, making it unchecked, the QSS file named Light.qss is applied but this time the font is set to the default font (MS Shell Dlg 2, 8.25 point):

    New_3.PNG

    I am not changing the font-related property of anything in QSS file at all. Why is this happening? and why it doesn't change the font when the QSS file is applied the first time (It doesn't matter if Light.qss is applied first or Dark.qss is applied first, the font only changes after the second time a QSS file is applied). If it helps, I am using Qt Designer in Visual Studio 2019, here is my mainWindow.cpp file:

    #include "mainWindow.h"
    #include <QFile>
    
    mainWindow::mainWindow(QWidget *parent)
        : QMainWindow(parent)
    {
        ui.setupUi(this);
     
        connect(ui.checkBox, &QCheckBox::stateChanged, this, &mainWindow::on_checkBox_stateChanged);
    }
    
    void mainWindow::on_checkBox_stateChanged(int state)
    {
        if(state)
        {
            str = ":/QSSFiles/Dark.qss";
        }
        else
        {
            str = ":/QSSFiles/Light.qss";
        }
        QFile StyleFile(str);
        StyleFile.open(QFile::ReadOnly);
        QString style(StyleFile.readAll());
        this->setStyleSheet(style);
    }
    


  • Hi, I also have been struck by this issue with font changing only after the 2nd attempt (it's probably a feature more than a bug, also it does not occur on Linux, only on Mac and Windows).
    To get around it, in my mainwindow.cpp constructor, I do a dummy setFont() call before the real one, like this:

    ...
    setFont(QFont("qwrwtopetyi"));   // anything goes (font does not have to exist)
    setFont(QFont("Courier"));       // the real McCoy
    ...


  • @hskoglund Hi! I tried your method, but the font is still changing after 2nd time I apply QSS file.



  • Yes you're right, my fix was for an app without any style sheets.

    Using style sheets, the normal Qt API calls like setFont() are left biting the dust, and any custom settings in Qt Creator's designer (like your Segoe Print 12 setting) also will not have any effect once you've entered the realm of style sheets (That's why the font gets kicked back to the Qt Creator default MS Shell Dlg 2)

    Instead, you'll have to specify the font as well in your style sheet, say like this:

    setStyleSheet("QLabel { background-color: yellow; font: 12pt \"Segoe Print\"; }");
    

Log in to reply