Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. partially update default stylesheet
Forum Updated to NodeBB v4.3 + New Features

partially update default stylesheet

Scheduled Pinned Locked Moved Unsolved General and Desktop
21 Posts 6 Posters 327 Views 4 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    T Offline
    tech032142
    wrote last edited by tech032142
    #10

    @JonB interesting but they both do not work
    setStyleSheet("QGroupBox { border-color: white; }");
    setStyleSheet("border-color: white;");

    even tho docs say (https://doc.qt.io/qt-6/stylesheet-reference.html#border-color)

    This property is supported by QAbstractItemView subclasses, QAbstractSpinBox subclasses, QCheckBox, QComboBox, QFrame, QGroupBox, QLabel, QLineEdit, QMenu, QMenuBar, QPushButton, QRadioButton, QSplitter, QTextEdit, QToolTip, and plain QWidgets.

    JonBJ 1 Reply Last reply
    0
    • T tech032142

      @JonB interesting but they both do not work
      setStyleSheet("QGroupBox { border-color: white; }");
      setStyleSheet("border-color: white;");

      even tho docs say (https://doc.qt.io/qt-6/stylesheet-reference.html#border-color)

      This property is supported by QAbstractItemView subclasses, QAbstractSpinBox subclasses, QCheckBox, QComboBox, QFrame, QGroupBox, QLabel, QLineEdit, QMenu, QMenuBar, QPushButton, QRadioButton, QSplitter, QTextEdit, QToolTip, and plain QWidgets.

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote last edited by JonB
      #11

      @tech032142
      I have now had a chance to try your stuff out.

      I concur that you cannot set e.g. border-color on its own. It only works if you specify border-width & border-style as well, as in the example in the docs, though that does not mention this. Which is pretty crappy :(

      I realise that puts you back in the plain border situation, where you don't know what to pass for the other values. I tried both auto and default for those, which I thought I found worked elsewhere in something I did, but again no border shown. Googling for qt change border color only got me nothing useful and all examples use border or all 3 individual attributes with explicit values.

      Seems pretty disappointing to me, your objective is very reasonable. You might post a "bug" to the Qt bug tracker if you wish, but looks like you are stuck with this.

      P.S.
      I have gone typed in a detailed query to ChatGPT as follows:

      Another Qt widgets question. I want to apply a stylesheet which changes a widget's border-color alone, leaving the width and style unchanged. I tried e.g. setStylesheet("border-color: red") but this does not change the color. It seems you just either specify all 3 of border-color, border-style and border-width, or use the border attribute with all 3 specified. This is no good, as I only want to change the color and do not know what values to pass in for the other attributes, I want them to remain as whatever they are and only change the color. Any ideas?

      It then writes an essay in response including:

      Excellent question — and you’ve hit on one of the annoying limitations of Qt Style Sheets (QSS):

      🎯 You cannot change only part of a shorthand property (like border) without re-specifying the others.

      Let’s unpack this and see what you can do.

      Why border-color alone doesn’t work

      Qt doesn’t merge this with the existing style; it replaces it.
      The style engine basically reinterprets all style rules for the widget from scratch — and since no border-style or border-width is defined, Qt considers the border as “not drawn”.

      So unless all three are specified, you won’t see a border at all.

      3 of the 5 options it presented basically say the same as I did --- you cannot get the existing values to use when you must specify all 3! Which only leaves:

      Option 3: Use a QPalette instead

      If your goal is just to change the color of something border-like (e.g. a line edit’s frame), sometimes you can control that through the palette rather than QSS:

      QPalette p = widget->palette();
      p.setColor(QPalette::Highlight, Qt::red);
      widget->setPalette(p);
      

      This won’t always affect borders (depends on the widget and style), but it’s more “cooperative” with the existing style.

      Option 5: Custom painting

      If you really must have runtime dynamic borders independent of QSS merging behavior, you can subclass the widget and override paintEvent(), painting your own border with QPainter::setPen(QColor(...)).
      This gives full control but is heavier.

      And btw, when I further asked as an example

      QFrame widget and no stylesheet of my own, so system style where I only want to change the color and preserve the other attributes

      It came back with

      Perfect — that makes it clearer 👍

      So, you’ve got a plain QFrame (using the system or Fusion style, no custom QSS), and you just want to change the border color — keeping the system border’s width and style exactly as they are.

      Here’s the key point:

      Qt’s built-in (non-stylesheet) drawing of QFrame borders is controlled entirely by its frame shape and shadow, not by stylesheet borders.

      That means:

      QFrame doesn’t actually use border-color at all unless you give it a full QSS-defined border.

      The border you see from setFrameShape(QFrame::Box) or similar comes from the QStyle, not from border: in CSS.

      As soon as you apply any stylesheet that mentions border, you override the QStyle-based border completely — losing its width, sunken/raised shadow effect, etc.

      And then confirmed that the only way to do this is via your own painting:

      Clean, working solution: subclass and paint the border color yourself

      Here’s how you can keep the system border’s width/style but recolor it:

      #include <QFrame>
      #include <QPainter>

      class ColorFrame : public QFrame
      {
      Q_OBJECT
      public:
      explicit ColorFrame(QWidget *parent = nullptr)
      : QFrame(parent), m_borderColor(Qt::red) {}

      void setBorderColor(const QColor &color)
      {
          m_borderColor = color;
          update();
      }
      

      protected:
      void paintEvent(QPaintEvent *event) override
      {
      // Let QFrame draw its normal frame (style-dependent)
      QFrame::paintEvent(event);

          // Then draw a colored overlay matching the frame rect
          QPainter p(this);
          p.setRenderHint(QPainter::Antialiasing, false);
      
          QPen pen(m_borderColor);
          pen.setWidth(frameWidth()); // use QFrame’s existing width
          p.setPen(pen);
          p.setBrush(Qt::NoBrush);
          p.drawRect(rect().adjusted(frameWidth()/2, frameWidth()/2,
                                     -frameWidth()/2, -frameWidth()/2));
      }
      

      private:
      QColor m_borderColor;
      };

      Usage:

      ColorFrame *f = new ColorFrame;
      f->setFrameShape(QFrame::Box);
      f->setBorderColor(Qt::red);

      ✅ This approach:

      Preserves the system’s QStyle-drawn frame shape & width.

      Only overlays a color tint on the same border region.

      Doesn’t interfere with QSS, palettes, or shadows.

      💡 Alternative: draw only the colored border (no system one)

      If you don’t care about keeping the 3D “sunken/raised” look:

      frame->setStyleSheet("border: 1px solid red;");

      That’s simpler but replaces the native frame entirely.

      🧭 Bottom line

      You cannot change just border-color on a system-style QFrame via QSS.

      To truly preserve system width/style and only recolor, you must draw it yourself (as above).

      Qt Style Sheets are not additive with system style — they replace it.

      Qt’s stylesheet system looks like CSS, but it’s really a kind of “all-or-nothing skinning layer.” Once you touch any border property, you’ve opted out of the native style drawing for that element.

      Your instincts were exactly right: if you only want to tweak one aspect (like color) and keep everything else system-driven, you either need to subclass and paint, or structure your styles so that you always specify the complete border: shorthand.

      Which btw confirms what I tend to find with ChatGPT --- it tells you about the same as you can find out yourself with judicious Googling, not much else... :)

      Hopefully the above/this rather long answer will be of use to anyone else who wishes to achieve this in the future.

      T 1 Reply Last reply
      0
      • JonBJ JonB

        @tech032142
        I have now had a chance to try your stuff out.

        I concur that you cannot set e.g. border-color on its own. It only works if you specify border-width & border-style as well, as in the example in the docs, though that does not mention this. Which is pretty crappy :(

        I realise that puts you back in the plain border situation, where you don't know what to pass for the other values. I tried both auto and default for those, which I thought I found worked elsewhere in something I did, but again no border shown. Googling for qt change border color only got me nothing useful and all examples use border or all 3 individual attributes with explicit values.

        Seems pretty disappointing to me, your objective is very reasonable. You might post a "bug" to the Qt bug tracker if you wish, but looks like you are stuck with this.

        P.S.
        I have gone typed in a detailed query to ChatGPT as follows:

        Another Qt widgets question. I want to apply a stylesheet which changes a widget's border-color alone, leaving the width and style unchanged. I tried e.g. setStylesheet("border-color: red") but this does not change the color. It seems you just either specify all 3 of border-color, border-style and border-width, or use the border attribute with all 3 specified. This is no good, as I only want to change the color and do not know what values to pass in for the other attributes, I want them to remain as whatever they are and only change the color. Any ideas?

        It then writes an essay in response including:

        Excellent question — and you’ve hit on one of the annoying limitations of Qt Style Sheets (QSS):

        🎯 You cannot change only part of a shorthand property (like border) without re-specifying the others.

        Let’s unpack this and see what you can do.

        Why border-color alone doesn’t work

        Qt doesn’t merge this with the existing style; it replaces it.
        The style engine basically reinterprets all style rules for the widget from scratch — and since no border-style or border-width is defined, Qt considers the border as “not drawn”.

        So unless all three are specified, you won’t see a border at all.

        3 of the 5 options it presented basically say the same as I did --- you cannot get the existing values to use when you must specify all 3! Which only leaves:

        Option 3: Use a QPalette instead

        If your goal is just to change the color of something border-like (e.g. a line edit’s frame), sometimes you can control that through the palette rather than QSS:

        QPalette p = widget->palette();
        p.setColor(QPalette::Highlight, Qt::red);
        widget->setPalette(p);
        

        This won’t always affect borders (depends on the widget and style), but it’s more “cooperative” with the existing style.

        Option 5: Custom painting

        If you really must have runtime dynamic borders independent of QSS merging behavior, you can subclass the widget and override paintEvent(), painting your own border with QPainter::setPen(QColor(...)).
        This gives full control but is heavier.

        And btw, when I further asked as an example

        QFrame widget and no stylesheet of my own, so system style where I only want to change the color and preserve the other attributes

        It came back with

        Perfect — that makes it clearer 👍

        So, you’ve got a plain QFrame (using the system or Fusion style, no custom QSS), and you just want to change the border color — keeping the system border’s width and style exactly as they are.

        Here’s the key point:

        Qt’s built-in (non-stylesheet) drawing of QFrame borders is controlled entirely by its frame shape and shadow, not by stylesheet borders.

        That means:

        QFrame doesn’t actually use border-color at all unless you give it a full QSS-defined border.

        The border you see from setFrameShape(QFrame::Box) or similar comes from the QStyle, not from border: in CSS.

        As soon as you apply any stylesheet that mentions border, you override the QStyle-based border completely — losing its width, sunken/raised shadow effect, etc.

        And then confirmed that the only way to do this is via your own painting:

        Clean, working solution: subclass and paint the border color yourself

        Here’s how you can keep the system border’s width/style but recolor it:

        #include <QFrame>
        #include <QPainter>

        class ColorFrame : public QFrame
        {
        Q_OBJECT
        public:
        explicit ColorFrame(QWidget *parent = nullptr)
        : QFrame(parent), m_borderColor(Qt::red) {}

        void setBorderColor(const QColor &color)
        {
            m_borderColor = color;
            update();
        }
        

        protected:
        void paintEvent(QPaintEvent *event) override
        {
        // Let QFrame draw its normal frame (style-dependent)
        QFrame::paintEvent(event);

            // Then draw a colored overlay matching the frame rect
            QPainter p(this);
            p.setRenderHint(QPainter::Antialiasing, false);
        
            QPen pen(m_borderColor);
            pen.setWidth(frameWidth()); // use QFrame’s existing width
            p.setPen(pen);
            p.setBrush(Qt::NoBrush);
            p.drawRect(rect().adjusted(frameWidth()/2, frameWidth()/2,
                                       -frameWidth()/2, -frameWidth()/2));
        }
        

        private:
        QColor m_borderColor;
        };

        Usage:

        ColorFrame *f = new ColorFrame;
        f->setFrameShape(QFrame::Box);
        f->setBorderColor(Qt::red);

        ✅ This approach:

        Preserves the system’s QStyle-drawn frame shape & width.

        Only overlays a color tint on the same border region.

        Doesn’t interfere with QSS, palettes, or shadows.

        💡 Alternative: draw only the colored border (no system one)

        If you don’t care about keeping the 3D “sunken/raised” look:

        frame->setStyleSheet("border: 1px solid red;");

        That’s simpler but replaces the native frame entirely.

        🧭 Bottom line

        You cannot change just border-color on a system-style QFrame via QSS.

        To truly preserve system width/style and only recolor, you must draw it yourself (as above).

        Qt Style Sheets are not additive with system style — they replace it.

        Qt’s stylesheet system looks like CSS, but it’s really a kind of “all-or-nothing skinning layer.” Once you touch any border property, you’ve opted out of the native style drawing for that element.

        Your instincts were exactly right: if you only want to tweak one aspect (like color) and keep everything else system-driven, you either need to subclass and paint, or structure your styles so that you always specify the complete border: shorthand.

        Which btw confirms what I tend to find with ChatGPT --- it tells you about the same as you can find out yourself with judicious Googling, not much else... :)

        Hopefully the above/this rather long answer will be of use to anyone else who wishes to achieve this in the future.

        T Offline
        T Offline
        tech032142
        wrote last edited by tech032142
        #12

        @JonB I ended up going with a custom stylesheet, I understand that qss does not exactly work like css but why the background color changes when I change the border styles :) , it feels like setStyleSheet just drops all the defaults when called , anyways thank you for your help

        Chris KawaC 1 Reply Last reply
        0
        • T tech032142

          @JonB I ended up going with a custom stylesheet, I understand that qss does not exactly work like css but why the background color changes when I change the border styles :) , it feels like setStyleSheet just drops all the defaults when called , anyways thank you for your help

          Chris KawaC Online
          Chris KawaC Online
          Chris Kawa
          Lifetime Qt Champion
          wrote last edited by
          #13

          @tech032142 The widget uses your default platform style, which often draws the border and background with some OS provided images or brushes. When you call setStyleSheet you're changing the style of your widget to Qt's StylesheetStyle, so you're no longer using the platform style on any parts of the widget. In some cases, if platform style allows it, Qt can apply the qss style to just some elements without completely replacing the style, but that is not the case for border (often text color and such, but it differs on different platforms and is not portable).

          JonBJ T 2 Replies Last reply
          3
          • Chris KawaC Chris Kawa

            @tech032142 The widget uses your default platform style, which often draws the border and background with some OS provided images or brushes. When you call setStyleSheet you're changing the style of your widget to Qt's StylesheetStyle, so you're no longer using the platform style on any parts of the widget. In some cases, if platform style allows it, Qt can apply the qss style to just some elements without completely replacing the style, but that is not the case for border (often text color and such, but it differs on different platforms and is not portable).

            JonBJ Offline
            JonBJ Offline
            JonB
            wrote last edited by
            #14

            @Chris-Kawa said in partially update default stylesheet:

            if platform style allows it, Qt can apply the qss style to just some elements without completely replacing the style, but that is not the case for border (often text color and such, but it differs on different platforms and is not portable).

            Yes, but I never know which things can be changed without losing native styling and which cannot.

            Christian EhrlicherC 1 Reply Last reply
            0
            • JonBJ JonB

              @Chris-Kawa said in partially update default stylesheet:

              if platform style allows it, Qt can apply the qss style to just some elements without completely replacing the style, but that is not the case for border (often text color and such, but it differs on different platforms and is not portable).

              Yes, but I never know which things can be changed without losing native styling and which cannot.

              Christian EhrlicherC Offline
              Christian EhrlicherC Offline
              Christian Ehrlicher
              Lifetime Qt Champion
              wrote last edited by
              #15

              @JonB said in partially update default stylesheet:

              Yes, but I never know which things can be changed without losing native styling and which cannot.

              Because this depends on the underlying style which defines what can be changed and what not without breaking the rest.

              Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
              Visit the Qt Academy at https://academy.qt.io/catalog

              JonBJ 1 Reply Last reply
              0
              • Christian EhrlicherC Christian Ehrlicher

                @JonB said in partially update default stylesheet:

                Yes, but I never know which things can be changed without losing native styling and which cannot.

                Because this depends on the underlying style which defines what can be changed and what not without breaking the rest.

                JonBJ Offline
                JonBJ Offline
                JonB
                wrote last edited by
                #16

                @Christian-Ehrlicher
                I understand that, but as a dev I don't know which they are and which not. Just saying. At least that explains why sometimes you can make a change without breaking windowing style and sometimes you lose it.

                Christian EhrlicherC 1 Reply Last reply
                0
                • Chris KawaC Chris Kawa

                  @tech032142 The widget uses your default platform style, which often draws the border and background with some OS provided images or brushes. When you call setStyleSheet you're changing the style of your widget to Qt's StylesheetStyle, so you're no longer using the platform style on any parts of the widget. In some cases, if platform style allows it, Qt can apply the qss style to just some elements without completely replacing the style, but that is not the case for border (often text color and such, but it differs on different platforms and is not portable).

                  T Offline
                  T Offline
                  tech032142
                  wrote last edited by
                  #17

                  @Chris-Kawa It makes more sense now, i couldn't find this in the docs maybe I missed it ?

                  1 Reply Last reply
                  0
                  • JonBJ JonB

                    @Christian-Ehrlicher
                    I understand that, but as a dev I don't know which they are and which not. Just saying. At least that explains why sometimes you can make a change without breaking windowing style and sometimes you lose it.

                    Christian EhrlicherC Offline
                    Christian EhrlicherC Offline
                    Christian Ehrlicher
                    Lifetime Qt Champion
                    wrote last edited by
                    #18

                    @JonB said in partially update default stylesheet:

                    At least that explains why sometimes you can make a change without breaking windowing style and sometimes you lose it.

                    Correct - it sometimes depends even on the underlying style.

                    Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                    Visit the Qt Academy at https://academy.qt.io/catalog

                    1 Reply Last reply
                    0
                    • T tech032142

                      I am on macOS Sonoma with Qt 6.9.3,

                      the first image is untouched no setStyleSheet calls, the other one is after setting styles

                      My question is :
                      setStyleSheet resets all style rules how do I preserve everything and just change the border color ?

                      I also tried

                      "QGroupBox { border : 2px solid #CCCCCC}"

                      I am extending QGroupBox in that class by the way

                      New Project.jpg

                      S Offline
                      S Offline
                      SimonSchroeder
                      wrote last edited by
                      #19

                      @tech032142 said in partially update default stylesheet:

                      how do I preserve everything and just change the border color ?

                      This is general problem with stylesheets: You don't.

                      My personal experience (where it is most obvious) is the following: On Windows, by default, the "Ok" and "Cancel" buttons in a dialog have the same width. However, once you apply any stylesheet the "Ok" buttons is smaller than the "Cancel" button because the text is shorter. Applying any stylesheet at all will mess with several aspects of layouts and designs. Still, there is no better general options than to use stylesheets.

                      @JonB said in partially update default stylesheet:

                      Yes, but I never know which things can be changed without losing native styling and which cannot.

                      In a perfect world we could just adapt the palette instead of setting a stylesheet (at least for color). It's not gonna happen.

                      JonBJ 1 Reply Last reply
                      0
                      • S SimonSchroeder

                        @tech032142 said in partially update default stylesheet:

                        how do I preserve everything and just change the border color ?

                        This is general problem with stylesheets: You don't.

                        My personal experience (where it is most obvious) is the following: On Windows, by default, the "Ok" and "Cancel" buttons in a dialog have the same width. However, once you apply any stylesheet the "Ok" buttons is smaller than the "Cancel" button because the text is shorter. Applying any stylesheet at all will mess with several aspects of layouts and designs. Still, there is no better general options than to use stylesheets.

                        @JonB said in partially update default stylesheet:

                        Yes, but I never know which things can be changed without losing native styling and which cannot.

                        In a perfect world we could just adapt the palette instead of setting a stylesheet (at least for color). It's not gonna happen.

                        JonBJ Offline
                        JonBJ Offline
                        JonB
                        wrote last edited by
                        #20

                        @SimonSchroeder
                        I come from an HTML/CSS background. And therefore web pages/elements, not native windowing system ones. In the former I have no trouble adjusting any individual element style attribute, and if I need to I can read back existing attribute values e.g. from JavaScript. I realise this is not the same for Qt/QSS, which is trying to do some CSS against non-CSS-HTML windowing widgets, but that is where it gets "complicated/disappointing" to my experience/expectations.

                        1 Reply Last reply
                        0
                        • SGaistS Offline
                          SGaistS Offline
                          SGaist
                          Lifetime Qt Champion
                          wrote last edited by
                          #21

                          Hi,

                          Another option is to create a QProxyStyle to do the painting you want.

                          Interested in AI ? www.idiap.ch
                          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                          1 Reply Last reply
                          0

                          • Login

                          • Login or register to search.
                          • First post
                            Last post
                          0
                          • Categories
                          • Recent
                          • Tags
                          • Popular
                          • Users
                          • Groups
                          • Search
                          • Get Qt Extensions
                          • Unsolved