Skip to content

Say No to Qt Style Sheets Making the Right Choice Between QStyle and Qt Style Sheets, Upfront

You have two choices when it comes to giving a custom style to your Qt widgets.

Qt Style Sheets are very convenient for getting started — just a few CSS-like rules, and they work.

It is our experience, however, that Qt Style Sheets create too much trouble and a QStyle subclass (*) gives a better solution, in the long run.

The following chart compares the two choices, to show you why a QStyle subclass trumps Qt Style Sheets:

Scenario

Qt Style Sheets

QStyle

Calling setFont/setPalette

No effect (rather unexpected), even if the style sheet has nothing to do with colors

Works as usual

Changing the system colors

No effect — the styled widgets don’t adapt to the new colors, even if the stylesheet has nothing to do with colors

Works as usual — the widgets use the new colors via the updated QPalette

Achieving 100% of the styling requirements

Style sheets allow you to do a number of things, but not everything. If there’s no support for a specific customization, there’s no solution.

QStyle subclasses in C++ give full control, as long as the widget actually delegates to the style. (Note that style sheets are implemented as an internal QStyle subclass. So, by definition, the flexibility given by custom QStyle subclasses is greater or equal.)

Mixing custom styling with native styling

Stylesheets do not mix well with QProxyStyles or other QStyle subclasses. This makes it even harder to gradually move away from the stylesheet solution. One specific example for proof: a stylesheet that simply sets a background color will lead to many of the style’s methods not being called because the style sheet style does many things on its own (ex: CT_SpinBox).

QProxyStyle allows you to tweak just one aspect and leave the rest to the native style for the platform.

Making a specific window unstyled (e.g.,

file dialog)

Very complicated (impacts all CSS rules)

Simply call QWidget::setStyle on other windows and not on that one.

Scaling for complex needs

Actual management of the stylesheet data does not scale (no include mechanism, etc.), calling for super-complicated selectors.

The C++ code of the QStyle subclass can call into helper classes, one per type of widget. This is the way KDAB develops widget styles these days, to avoid writing a 20000-line class.

Reacting on changes

Selectors on properties do not get reevaluated when the properties change, forcing hacks such as reset of a style sheet with the associated cost.

The setter calls update(); the paint event calls into the style again.

Performance considerations when styling many independent widgets

Each call to setStyleSheet triggers parsing, which can be slow if done too often (e.g., when creating 50 buttons, each one calling setStylesheet(“…”)). The usual solution is a single application-wide stylesheet, but that’s a pain to maintain and it hits the issue of management of the style sheet data, above.

No parsing necessary. Either all widgets use the application style, or individual widgets can point to a specific style.

Performance considerations when

reparenting a widget

Each reparenting triggers clearing the stylesheet rules cache and recalculating everything.

Reparenting has no performance impact with QStyle.

 

(*) To be clear, when we say “a QStyle subclass,” we don’t mean you should subclass QStyle directly. Usually, you would start by subclassing QProxyStyle, so that all widgets still appear on the screen. Then you can style them incrementally and, when you’re done, you can switch to QCommonStyle as the base class, if the appearance should be the same on all platforms.

As you can see, we find that a QStyle subclass is overall a much better solution for styling widgets than is Qt Style Sheets. It’s a bit more difficult to write, but the mechanism is much more powerful and performant.

If you would like the KDAB experts to help you write such a widget style, don’t hesitate to contact us.

About KDAB

If you like this article and want to read similar material, consider subscribing via our RSS feed.

Subscribe to KDAB TV for similar informative short video content.

KDAB provides market leading software consulting and development services and training in Qt, C++ and 3D/OpenGL. Contact us.

FacebookTwitterLinkedInEmail

7 thoughts on “Say No to Qt Style Sheets”

  1. Are there online example of modern theming using QStyle subclass?
    Also I would like to comment that stylesheets can use the current palette in their definition
    ex:
    QAbstractButton {
    border-color: palette(highlight);
    color: palette(bright-text);
    }

    1. David Faure

      https://doc.qt.io/qt-6/qstyle.html has some example code, as well as https://doc.qt.io/qt-6/qtwidgets-widgets-styles-example.html. The look is definitely not modern, but the API hasn’t changed, and everything you can do with a stylesheet, you can do with a style subclass (and more).

      Indeed stylesheets can call into the palette. The default behavior though, when the stylesheet doesn’t mention colors, doesn’t play well with the palette. See the documentation for QWidget::setPalette which says “Warning: Do not use this function in conjunction with Qt Style Sheets.”. And I remember hitting such problems, they are not just theoretical. I don’t have a testcase at hand though.

  2. I really like the blog posts from KDAB and already learned a lot of interesting things from it, but this time I diasgree.

    Styling Qt application with styleheets is a lot easier then using QStyle. Using styleheets allows for a very good separation between UI implementation and design. If you know CSS from HTML, then you already know how to use Qt stylesheets.

    We styled a complete application with CSS (https://cetoni.com/cetoni-elements/) and we do not see any performance issues. Some of the mentioned points in the blog post are quite “theoretical” and do not matter in most real world applications. CSS gives you a great flexibility to quickly fix or change the styling without the need to change and recompile C++ source code. Changing and testing style changes with CSS is extremely quick.

    The use of the Qt Advanced Stylesheets Library (https://github.com/githubuser0xFFFF/Qt-Advanced-Stylesheets) makes Qt stylesheets even more powerful and allows you to switch the complete application theme including Palette and Icon colors using Qt stylehsheets (https://youtu.be/xWTpCwCz8dI).

    Hence my opinion: Say Yes to Qt Style Sheets ;o)

    1. We have a widgets app styled completely with style sheets and we’re happy with it. I did not find the QStyle method to be very accessible.

      We’ve integrated the SASS stylesheet compiler into our app so that we can determine some parts of the style dynamically, based on platform, DPI, and potentially user preferences like high contrast etc. This gives us access to much better syntax and better selectors too.

    2. David Faure

      I’m glad to see diverging opinions, debating makes things interesting 🙂

      The need to write an additional library on top of what is provided by Qt, partially proves the point that the stylesheet support in Qt is not completely optimal, though.

      About the points being theoretical: they all come from our own actual experience. For instance the one about wanting not to affect the style of file dialogs on Linux is the reason I ported the opensource music application rosegarden from Qt stylesheets to a QStyle.

  3. I certainly need look closer at QStyle. Currently, I’m just using Qt Style Sheets, as it’s served my needs. The first question that comes to mind is can the user supply style information on their own to the app and have it drive QStyle? Today, one of the strong benefits of using Qt Style Sheets is quite often an end-user will ask “how can I change such and such” and want to change a specific font or color on some random widget you never even thought about needing a user preference. And it’s nice to just point them to writing a simple style sheet and passing it as a command-line argument when calling the app and presto, it works like magic as if we were thinking of their need to change that widget from the beginning. Will that still work with QStyle (or can be made to work)?

    In the documentation of QStyle, I see it says “Warning: Qt style sheets are currently not supported for custom QStyle subclasses. We plan to address this in some future release.”. Does that relate to being able to pass external style sheets to the app for driving that as I describe above? Also, is that specific to just Qt 6 or does it go back to Qt 5 or even Qt 4 days too?

    There’s some good sounding benefits of QStyle, as described, but I need to learn more about it.

    1. David Faure

      The ability for users to customize things is undoubtedly the appeal of stylesheets, and QStyle doesn’t offer that out of the box (the only way to get anywhere near that is to read configuration from the C++ style code, which allows for some things but is of course not as flexible).

      “Qt style sheets are currently not supported for custom QStyle subclasses” doesn’t really make sense to me, actually.
      I don’t see how this is worse than the usual use of stylesheets, applied on top of the default widget style. I suppose someone hit some of the problems mixing styles and stylesheets (as in our table row that talks about mixing) and added this as documentation (I can’t get more details though, this bit of documentation predates the public git repository for Qt).

      So yeah, I think it makes sense to provide a QStyle and still let users play with stylesheets on top for light customization, as a best-of-both-worlds compromise.

      All this applies to Qt 4, 5, and 6, there hasn’t been a major architectural change in that area.

Leave a Reply

Your email address will not be published.