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. Qt Style Sheets cascading classes selectors
Forum Updated to NodeBB v4.3 + New Features

Qt Style Sheets cascading classes selectors

Scheduled Pinned Locked Moved Solved General and Desktop
qcssstylesheet
29 Posts 4 Posters 33.8k Views 2 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.
  • JonBJ Offline
    JonBJ Offline
    JonB
    wrote on last edited by JonB
    #1

    In HTML/CSS, I assign an HTML element a class explicitly via class="myClass" (JavaScript className attribute). And in all modern browsers I can set it to a (space-separated) list of classes. This means I can write stuff like:

    .colorRed: { color: red; }
    .colorGreen: { color: green; }
    .fontBold: { font-weight: bold; }
    ...
    
    <span class="colorRed fontBold ...">Label</span>
    <input class="colorGreen fontBold ..." type="text" />
    ...
    

    I can thus build up individual style attributes and apply them selectively to elements, entirely as I please.

    As I understand it, in QCSS however there is no way to associate arbitrary class names with a widget. Instead, I must use the actual code C++/Python classes to achieve this cascading, like:

    .QLabel { font-weight: bold; }
    .RedLabel { color: red; }
    .GreenLabel { color: green; }
    .QTextEdit { font-weight: bold; }
    .RedTextEdit { color: red; }
    .GreenTextEdit { color: green; }
    ...
    
    class RedLabel(QLabel): ...
    class GreenLabel(QLabel): ...
    class RedTextEdit(QTextEdit): ...
    class GreenTextEdit(QTextEdit): ...
    ...
    

    This is, of course, only example. I don't want an answer to this specific example. [Please extrapolate to what is necessary as the number of class-attributes grows.]

    There are all sorts of individual class-attributes I want to define to apply to all sorts of elements (widgets), building them up bit-by-bit in a consistent fashion. Having to define actually code classes to achieve this is a royal pain, requires code changing, difficult to maintain, etc.

    Am I right that this is the only way to do this in QCSS? There is no way to assign arbitrary CSS class names to an individual widgets quite independent of the actual code class hierarchy?

    J.HilkJ 1 Reply Last reply
    1
    • JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by JonB
      #29

      To summarise for anyone reading this. Thanks to the answers above.

      • You can assign a dynamic property, with a name and value of your choice, via QWidget.setProperty("cssClass", "large").

      • The stylesheet can match this via selector *[cssClass="large"] { ... }.

      • You can assign multiple values to the property via QWidget.setProperty("cssClass", [ "bold", "large", "rounded" ]). (Or it accepts a space-separated string via "bold large rounded".)

      • The stylesheet can match one of the values via selector *[cssClass~="large"] { ... } (note the ~=).

      Note that property named class is a special one, referring to the Python/C++ code class of the widget, which you probably should not assign to.

      1 Reply Last reply
      2
      • JonBJ JonB

        In HTML/CSS, I assign an HTML element a class explicitly via class="myClass" (JavaScript className attribute). And in all modern browsers I can set it to a (space-separated) list of classes. This means I can write stuff like:

        .colorRed: { color: red; }
        .colorGreen: { color: green; }
        .fontBold: { font-weight: bold; }
        ...
        
        <span class="colorRed fontBold ...">Label</span>
        <input class="colorGreen fontBold ..." type="text" />
        ...
        

        I can thus build up individual style attributes and apply them selectively to elements, entirely as I please.

        As I understand it, in QCSS however there is no way to associate arbitrary class names with a widget. Instead, I must use the actual code C++/Python classes to achieve this cascading, like:

        .QLabel { font-weight: bold; }
        .RedLabel { color: red; }
        .GreenLabel { color: green; }
        .QTextEdit { font-weight: bold; }
        .RedTextEdit { color: red; }
        .GreenTextEdit { color: green; }
        ...
        
        class RedLabel(QLabel): ...
        class GreenLabel(QLabel): ...
        class RedTextEdit(QTextEdit): ...
        class GreenTextEdit(QTextEdit): ...
        ...
        

        This is, of course, only example. I don't want an answer to this specific example. [Please extrapolate to what is necessary as the number of class-attributes grows.]

        There are all sorts of individual class-attributes I want to define to apply to all sorts of elements (widgets), building them up bit-by-bit in a consistent fashion. Having to define actually code classes to achieve this is a royal pain, requires code changing, difficult to maintain, etc.

        Am I right that this is the only way to do this in QCSS? There is no way to assign arbitrary CSS class names to an individual widgets quite independent of the actual code class hierarchy?

        J.HilkJ Offline
        J.HilkJ Offline
        J.Hilk
        Moderators
        wrote on last edited by J.Hilk
        #2

        @JNBarchan hi, actually you can asign specific class names. For example:

        QPushButton#btnBack{border-image:url(:/data/NavIcons/btnPrev.png);}
        

        sets the stylesheet to all QPushButtons with the objectname btnBack

        you can also combine that with other default states
        or custom states(Q_Properties) as in this example:

        QPushButton#btnUnits[state = true]:pressed{border-image:url(:/data/NavIcons/Menu_Imp.png);}
        QPushButton#btnUnits:pressed{border-image:url(:/data/NavIcons/Menu_Si.png);}
        

        taken from my current project.


        Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


        Q: What's that?
        A: It's blue light.
        Q: What does it do?
        A: It turns blue.

        JonBJ 1 Reply Last reply
        0
        • J.HilkJ J.Hilk

          @JNBarchan hi, actually you can asign specific class names. For example:

          QPushButton#btnBack{border-image:url(:/data/NavIcons/btnPrev.png);}
          

          sets the stylesheet to all QPushButtons with the objectname btnBack

          you can also combine that with other default states
          or custom states(Q_Properties) as in this example:

          QPushButton#btnUnits[state = true]:pressed{border-image:url(:/data/NavIcons/Menu_Imp.png);}
          QPushButton#btnUnits:pressed{border-image:url(:/data/NavIcons/Menu_Si.png);}
          

          taken from my current project.

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by JonB
          #3

          @J.Hilk

          [Forget about "state selectors, like :pressed, they are not at issue.]

          Thanks, but I'm afraid that does not solve the problem. #id is available in HTML/CSS. But it does not allow for multiple classes (let alone that it relies on widget having a particular object name"), which is what I need.

          In HTML/CSS I can have multiple elements on same or multiple pages like:

          <span class="green bold tall sunken"></span>
          <span class="red bold tall outset"></span>
          <span class="bold short outset"></span>
          ...
          

          So I can build up each CSS class definition (of what bold, short, etc. are) separately and combine them at will. This is what we do in HTML/CSS, and I am stumped as to how to achieve it in Qt across "50 pages with 20 widgets each".

          I would need Qt to offer some equivalent of:

          label1 = QLabel()
          label1.classes = "green bold tall sunken"
          label2 = QLabel()
          label2.classes = "red bold tall outset"
          

          Do you follow why? And if Qt does not offer this, it will be almost impossible to achieve a maintainable set of QCSS definitions, which would be an awful shame.... :(

          J.HilkJ 1 Reply Last reply
          0
          • JonBJ JonB

            @J.Hilk

            [Forget about "state selectors, like :pressed, they are not at issue.]

            Thanks, but I'm afraid that does not solve the problem. #id is available in HTML/CSS. But it does not allow for multiple classes (let alone that it relies on widget having a particular object name"), which is what I need.

            In HTML/CSS I can have multiple elements on same or multiple pages like:

            <span class="green bold tall sunken"></span>
            <span class="red bold tall outset"></span>
            <span class="bold short outset"></span>
            ...
            

            So I can build up each CSS class definition (of what bold, short, etc. are) separately and combine them at will. This is what we do in HTML/CSS, and I am stumped as to how to achieve it in Qt across "50 pages with 20 widgets each".

            I would need Qt to offer some equivalent of:

            label1 = QLabel()
            label1.classes = "green bold tall sunken"
            label2 = QLabel()
            label2.classes = "red bold tall outset"
            

            Do you follow why? And if Qt does not offer this, it will be almost impossible to achieve a maintainable set of QCSS definitions, which would be an awful shame.... :(

            J.HilkJ Offline
            J.HilkJ Offline
            J.Hilk
            Moderators
            wrote on last edited by
            #4

            @JNBarchan mmh, I'm afraid, I'm not that involved/knowledgable with StyleSheets to give you a defenite Yes or No answer on this one.
            Maybe someone else can give you a better answer.

            Would comes to my mind right now, is, you could create multiple QSS-files that you add to your ressource file and load a specific one from inside your classes.


            Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


            Q: What's that?
            A: It's blue light.
            Q: What does it do?
            A: It turns blue.

            JonBJ 1 Reply Last reply
            0
            • J.HilkJ J.Hilk

              @JNBarchan mmh, I'm afraid, I'm not that involved/knowledgable with StyleSheets to give you a defenite Yes or No answer on this one.
              Maybe someone else can give you a better answer.

              Would comes to my mind right now, is, you could create multiple QSS-files that you add to your ressource file and load a specific one from inside your classes.

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by
              #5

              @J.Hilk
              Thanks for your attempt. I need a Qt stylesheet expert then... :)

              1 Reply Last reply
              0
              • webzoidW Offline
                webzoidW Offline
                webzoid
                wrote on last edited by
                #6

                @JNBarchan I use CSS heavily in my QWidget application and unfortunately I've also not come across a way to achieve this.

                What I've done in my application is to use a "dynamic property" called class and against this, I specify a CSS class which then links through to my stylesheet.

                For example, in the designer I have a QPushButton with a class of red, my stylesheet then contains:

                QPushButton[class="red"] {
                    background-color: red;
                }
                

                I know it isn't what you are looking for but given that QWidgets do not explicitly allow CSS classes to be bound to them (or chained), I think your best bet is to look for other options.

                1 Reply Last reply
                1
                • webzoidW Offline
                  webzoidW Offline
                  webzoid
                  wrote on last edited by
                  #7

                  Hold the phone!!

                  Ignore my answer.

                  Assign a dynamic property called "class" and in this, specify your class names (can be many), for example "red blue". Now, in your stylesheet if you have:

                  .red {
                      color: red;
                  }
                  
                  .blue {
                      background-color: blue;
                  }
                  

                  You will get a QPushButton with red text and blue background! It works

                  JonBJ J.HilkJ 2 Replies Last reply
                  2
                  • webzoidW webzoid

                    Hold the phone!!

                    Ignore my answer.

                    Assign a dynamic property called "class" and in this, specify your class names (can be many), for example "red blue". Now, in your stylesheet if you have:

                    .red {
                        color: red;
                    }
                    
                    .blue {
                        background-color: blue;
                    }
                    

                    You will get a QPushButton with red text and blue background! It works

                    JonBJ Offline
                    JonBJ Offline
                    JonB
                    wrote on last edited by
                    #8

                    @webzoid
                    Oooohhh, I have held the phone, and this looks perfect!

                    I am new to Qt, and I'm afraid I use Python/PyQt (and no Qt Creator). How (C++ will do) do I do:

                    Assign a dynamic property called "class"

                    ?

                    1 Reply Last reply
                    0
                    • webzoidW webzoid

                      Hold the phone!!

                      Ignore my answer.

                      Assign a dynamic property called "class" and in this, specify your class names (can be many), for example "red blue". Now, in your stylesheet if you have:

                      .red {
                          color: red;
                      }
                      
                      .blue {
                          background-color: blue;
                      }
                      

                      You will get a QPushButton with red text and blue background! It works

                      J.HilkJ Offline
                      J.HilkJ Offline
                      J.Hilk
                      Moderators
                      wrote on last edited by
                      #9

                      @webzoid wait wait, could you elaborate that example a bit for all us none StyleSheet Experts x)


                      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                      Q: What's that?
                      A: It's blue light.
                      Q: What does it do?
                      A: It turns blue.

                      1 Reply Last reply
                      0
                      • webzoidW Offline
                        webzoidW Offline
                        webzoid
                        wrote on last edited by
                        #10

                        @JNBarchan I believe the QObject::setProperty function is how you would assign a dynamic property in c++. See here

                        http://doc.qt.io/qt-5/qobject.html#setProperty

                        @J-Hilk I will post my worked example for download shortly...

                        JonBJ 1 Reply Last reply
                        1
                        • webzoidW Offline
                          webzoidW Offline
                          webzoid
                          wrote on last edited by webzoid
                          #11

                          Here's a QWidgets example:

                          https://drive.google.com/open?id=1XbOJgF6DNqsmq_JR5c9gfWiHv3poHPWV

                          The "style.css" file needs to live alongside the executable in order for this to work. Or change the code...

                          1 Reply Last reply
                          2
                          • webzoidW webzoid

                            @JNBarchan I believe the QObject::setProperty function is how you would assign a dynamic property in c++. See here

                            http://doc.qt.io/qt-5/qobject.html#setProperty

                            @J-Hilk I will post my worked example for download shortly...

                            JonBJ Offline
                            JonBJ Offline
                            JonB
                            wrote on last edited by
                            #12

                            @webzoid said in Qt Style Sheets cascading classes selectors:

                            @JNBarchan I believe the QObject::setProperty function is how you would assign a dynamic property in c++. See here

                            http://doc.qt.io/qt-5/qobject.html#setProperty

                            Hopefully, you are a hero(!), though not time to try it right now.

                            From the docs I note:

                            If the property is defined in the class using Q_PROPERTY then true is returned on success and false otherwise. If the property is not defined using Q_PROPERTY, and therefore not listed in the meta-object, it is added as a dynamic property and false is returned.

                            Being Python/PyQt, I don't know how (or even if it's possible) to do Q_PROPERTY. Assuming I can't, does your class property principle work OK if that is absent?

                            webzoidW J.HilkJ 2 Replies Last reply
                            0
                            • JonBJ JonB

                              @webzoid said in Qt Style Sheets cascading classes selectors:

                              @JNBarchan I believe the QObject::setProperty function is how you would assign a dynamic property in c++. See here

                              http://doc.qt.io/qt-5/qobject.html#setProperty

                              Hopefully, you are a hero(!), though not time to try it right now.

                              From the docs I note:

                              If the property is defined in the class using Q_PROPERTY then true is returned on success and false otherwise. If the property is not defined using Q_PROPERTY, and therefore not listed in the meta-object, it is added as a dynamic property and false is returned.

                              Being Python/PyQt, I don't know how (or even if it's possible) to do Q_PROPERTY. Assuming I can't, does your class property principle work OK if that is absent?

                              webzoidW Offline
                              webzoidW Offline
                              webzoid
                              wrote on last edited by
                              #13

                              @JNBarchan Unfortunately I'm coming from the Windows QWidget application side of things so I really can't comment on what Python/PyQt will do in this instance.

                              I have just done a test whereby I call the setProperty function from C++ as follows:

                              ui->pushButton->setProperty("class", "red thick-border");
                              

                              and the result is exactly the same as if I'd done it in the designer. Hopefully PyQt works in the same way.

                              JonBJ 1 Reply Last reply
                              1
                              • JonBJ JonB

                                @webzoid said in Qt Style Sheets cascading classes selectors:

                                @JNBarchan I believe the QObject::setProperty function is how you would assign a dynamic property in c++. See here

                                http://doc.qt.io/qt-5/qobject.html#setProperty

                                Hopefully, you are a hero(!), though not time to try it right now.

                                From the docs I note:

                                If the property is defined in the class using Q_PROPERTY then true is returned on success and false otherwise. If the property is not defined using Q_PROPERTY, and therefore not listed in the meta-object, it is added as a dynamic property and false is returned.

                                Being Python/PyQt, I don't know how (or even if it's possible) to do Q_PROPERTY. Assuming I can't, does your class property principle work OK if that is absent?

                                J.HilkJ Offline
                                J.HilkJ Offline
                                J.Hilk
                                Moderators
                                wrote on last edited by
                                #14

                                @JNBarchan Q_Property is part of QObject that is the essential part of what makes qt qt, so I would be seriously surpised if its not possible.

                                @webzoid thank you very much! That will help a lot of people for a long time ;-)


                                Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                                Q: What's that?
                                A: It's blue light.
                                Q: What does it do?
                                A: It turns blue.

                                webzoidW JonBJ 2 Replies Last reply
                                0
                                • J.HilkJ J.Hilk

                                  @JNBarchan Q_Property is part of QObject that is the essential part of what makes qt qt, so I would be seriously surpised if its not possible.

                                  @webzoid thank you very much! That will help a lot of people for a long time ;-)

                                  webzoidW Offline
                                  webzoidW Offline
                                  webzoid
                                  wrote on last edited by
                                  #15

                                  @J.Hilk It's definitely helped me already!

                                  1 Reply Last reply
                                  0
                                  • webzoidW webzoid

                                    @JNBarchan Unfortunately I'm coming from the Windows QWidget application side of things so I really can't comment on what Python/PyQt will do in this instance.

                                    I have just done a test whereby I call the setProperty function from C++ as follows:

                                    ui->pushButton->setProperty("class", "red thick-border");
                                    

                                    and the result is exactly the same as if I'd done it in the designer. Hopefully PyQt works in the same way.

                                    JonBJ Offline
                                    JonBJ Offline
                                    JonB
                                    wrote on last edited by JonB
                                    #16

                                    @webzoid

                                    @JNBarchan Unfortunately I'm coming from the Windows QWidget application side of things so I really can't comment on what Python/PyQt will do in this instance.

                                    No, we're on the same page there. I inherit from QWidget OK just like you do. But (I believe) you can do something like:

                                    class MyWidget : QWidget
                                    {
                                        Q_PROPERTY QString cssClass;  // declare cssClass member as a known property in MyWidget
                                        ...
                                        this.cssClass = "red blue";
                                    }
                                    

                                    I can't (don't know how to/if I can) use that Q_PROPERTY macro you have, so just:

                                    class MyWidget(QWidget)
                                    {
                                        ...
                                        self.cssClass = "red blue";
                                    }
                                    

                                    But I think you are not using Q_PROPERTY anywhere yourself, you just go ui->pushButton->setProperty("class", "red thick-border");, so your class is:

                                    therefore not listed in the meta-object, it is added as a dynamic property

                                    Is that correct for your C++ situation? Which is all I can do, and looks same as what you are doing to me, so I should be OK?

                                    1 Reply Last reply
                                    0
                                    • J.HilkJ J.Hilk

                                      @JNBarchan Q_Property is part of QObject that is the essential part of what makes qt qt, so I would be seriously surpised if its not possible.

                                      @webzoid thank you very much! That will help a lot of people for a long time ;-)

                                      JonBJ Offline
                                      JonBJ Offline
                                      JonB
                                      wrote on last edited by JonB
                                      #17

                                      @J.Hilk said in Qt Style Sheets cascading classes selectors:

                                      @JNBarchan Q_Property is part of QObject that is the essential part of what makes qt qt, so I would be seriously surpised if its not possible.

                                      ? a. I think it's a macro, so what is its expansion anyway? and b. in Python we do not even declare any member variables in a class (not my fault, I didn't choose Python), so ... ?

                                      J.HilkJ 1 Reply Last reply
                                      0
                                      • JonBJ JonB

                                        @J.Hilk said in Qt Style Sheets cascading classes selectors:

                                        @JNBarchan Q_Property is part of QObject that is the essential part of what makes qt qt, so I would be seriously surpised if its not possible.

                                        ? a. I think it's a macro, so what is its expansion anyway? and b. in Python we do not even declare any member variables in a class (not my fault, I didn't choose Python), so ... ?

                                        J.HilkJ Offline
                                        J.HilkJ Offline
                                        J.Hilk
                                        Moderators
                                        wrote on last edited by
                                        #18

                                        @JNBarchan said in Qt Style Sheets cascading classes selectors:

                                        @J.Hilk said in Qt Style Sheets cascading classes selectors:

                                        @JNBarchan Q_Property is part of QObject that is the essential part of what makes qt qt, so I would be seriously surpised if its not possible.

                                        ? a. I think it's a macro, so what is its expansion anyway? and b. in Python we do not even declare any member variables in a class (not my fault, I didn't choose Python), so ... ?

                                        Well, yes, technically its a Macro (I think), I found this webside Support for Qt Properties for PyQt5

                                        seems like a good place to start, I guess.


                                        Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                                        Q: What's that?
                                        A: It's blue light.
                                        Q: What does it do?
                                        A: It turns blue.

                                        raven-worxR 1 Reply Last reply
                                        1
                                        • J.HilkJ J.Hilk

                                          @JNBarchan said in Qt Style Sheets cascading classes selectors:

                                          @J.Hilk said in Qt Style Sheets cascading classes selectors:

                                          @JNBarchan Q_Property is part of QObject that is the essential part of what makes qt qt, so I would be seriously surpised if its not possible.

                                          ? a. I think it's a macro, so what is its expansion anyway? and b. in Python we do not even declare any member variables in a class (not my fault, I didn't choose Python), so ... ?

                                          Well, yes, technically its a Macro (I think), I found this webside Support for Qt Properties for PyQt5

                                          seems like a good place to start, I guess.

                                          raven-worxR Offline
                                          raven-worxR Offline
                                          raven-worx
                                          Moderators
                                          wrote on last edited by raven-worx
                                          #19

                                          @J.Hilk
                                          actually this is already stated in the docs.
                                          Altough i am surprised that it works when you assign a string with space-separated values instead of a QVariant containing a QStringList.

                                          --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                                          If you have a question please use the forum so others can benefit from the solution in the future

                                          JonBJ 2 Replies Last reply
                                          3
                                          • raven-worxR raven-worx

                                            @J.Hilk
                                            actually this is already stated in the docs.
                                            Altough i am surprised that it works when you assign a string with space-separated values instead of a QVariant containing a QStringList.

                                            JonBJ Offline
                                            JonBJ Offline
                                            JonB
                                            wrote on last edited by
                                            #20

                                            @raven-worx
                                            Thanks, I needed that link. I had not come across it, its discussion of setProperty(), dynamic properties, multiple properties, use of ~=, etc. Obscure (for me)!

                                            I see it says:

                                            In addition, the special class property is supported, for the name of the class.

                                            This might explain why my attempts so far to set & match my own property named class, as per @webzoid's suggestion, has not been working...!

                                            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