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.
  • W webzoid
    14 Dec 2017, 11:15

    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 Offline
    J Offline
    JonB
    wrote on 14 Dec 2017, 11:21 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
    • W webzoid
      14 Dec 2017, 11:15

      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 Offline
      J Offline
      J.Hilk
      Moderators
      wrote on 14 Dec 2017, 11:29 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
      • W Offline
        W Offline
        webzoid
        wrote on 14 Dec 2017, 11:33 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...

        J 1 Reply Last reply 14 Dec 2017, 12:00
        1
        • W Offline
          W Offline
          webzoid
          wrote on 14 Dec 2017, 11:40 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
          • W webzoid
            14 Dec 2017, 11:33

            @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...

            J Offline
            J Offline
            JonB
            wrote on 14 Dec 2017, 12:00 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?

            W J 2 Replies Last reply 14 Dec 2017, 12:06
            0
            • J JonB
              14 Dec 2017, 12:00

              @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?

              W Offline
              W Offline
              webzoid
              wrote on 14 Dec 2017, 12:06 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.

              J 1 Reply Last reply 14 Dec 2017, 12:19
              1
              • J JonB
                14 Dec 2017, 12:00

                @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 Offline
                J Offline
                J.Hilk
                Moderators
                wrote on 14 Dec 2017, 12:11 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.

                W J 2 Replies Last reply 14 Dec 2017, 12:17
                0
                • J J.Hilk
                  14 Dec 2017, 12:11

                  @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 ;-)

                  W Offline
                  W Offline
                  webzoid
                  wrote on 14 Dec 2017, 12:17 last edited by
                  #15

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

                  1 Reply Last reply
                  0
                  • W webzoid
                    14 Dec 2017, 12:06

                    @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.

                    J Offline
                    J Offline
                    JonB
                    wrote on 14 Dec 2017, 12:19 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 J.Hilk
                      14 Dec 2017, 12:11

                      @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 ;-)

                      J Offline
                      J Offline
                      JonB
                      wrote on 14 Dec 2017, 12:23 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 1 Reply Last reply 14 Dec 2017, 12:28
                      0
                      • J JonB
                        14 Dec 2017, 12:23

                        @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 Offline
                        J Offline
                        J.Hilk
                        Moderators
                        wrote on 14 Dec 2017, 12:28 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.

                        R 1 Reply Last reply 15 Dec 2017, 12:40
                        1
                        • J J.Hilk
                          14 Dec 2017, 12:28

                          @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.

                          R Offline
                          R Offline
                          raven-worx
                          Moderators
                          wrote on 15 Dec 2017, 12:40 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

                          J 2 Replies Last reply 15 Dec 2017, 12:55
                          3
                          • R raven-worx
                            15 Dec 2017, 12:40

                            @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.

                            J Offline
                            J Offline
                            JonB
                            wrote on 15 Dec 2017, 12:55 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
                            • R raven-worx
                              15 Dec 2017, 12:40

                              @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.

                              J Offline
                              J Offline
                              JonB
                              wrote on 15 Dec 2017, 13:08 last edited by JonB
                              #21

                              @raven-worx
                              I'm really struggling here, because what should be working just isn't. I'm not even as far as multiple property/space-separated strings, just one item:

                              1. I create a QLabel.

                              2. Stylesheet: (global, nothing else in it) QLabel { color: red; }

                              3. Change to: QLabel[cssClass="red"] { color: red; }, or to QLabel[cssClass~="red"] { color: red; }

                              4. Change code to: label.setProperty("cssClass", "red")

                              After #2 it's red. After #4 it ceases to be red :(

                              I know it's Python/PyQt --- and I can't test C++ or QML --- but I really think the setProperty() will be a straight, pass-through call.

                              Would someone be prepared to just try as simple as above?

                              R 1 Reply Last reply 15 Dec 2017, 13:18
                              0
                              • J JonB
                                15 Dec 2017, 13:08

                                @raven-worx
                                I'm really struggling here, because what should be working just isn't. I'm not even as far as multiple property/space-separated strings, just one item:

                                1. I create a QLabel.

                                2. Stylesheet: (global, nothing else in it) QLabel { color: red; }

                                3. Change to: QLabel[cssClass="red"] { color: red; }, or to QLabel[cssClass~="red"] { color: red; }

                                4. Change code to: label.setProperty("cssClass", "red")

                                After #2 it's red. After #4 it ceases to be red :(

                                I know it's Python/PyQt --- and I can't test C++ or QML --- but I really think the setProperty() will be a straight, pass-through call.

                                Would someone be prepared to just try as simple as above?

                                R Offline
                                R Offline
                                raven-worx
                                Moderators
                                wrote on 15 Dec 2017, 13:18 last edited by
                                #22

                                @JNBarchan
                                i never used PyQt in my life, so i have absolutely no experience with it.

                                Do you mean you change the stylesheet at runtime? Or do you just want to specify the stylesheet once from application startup and never change it again?

                                In c++ i would do this:

                                QLabel* label = new QLabel;
                                    label->setProperty("cssClass", QVariant::fromValue<QStringList>( QStringList() << "red" ) );
                                

                                and in the stylesheet:

                                QLabel[cssClass~="red"] { color: red; }
                                

                                I don't what the equivalent of a QStringList in PyQt.

                                --- 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

                                J 1 Reply Last reply 15 Dec 2017, 13:26
                                1
                                • R raven-worx
                                  15 Dec 2017, 13:18

                                  @JNBarchan
                                  i never used PyQt in my life, so i have absolutely no experience with it.

                                  Do you mean you change the stylesheet at runtime? Or do you just want to specify the stylesheet once from application startup and never change it again?

                                  In c++ i would do this:

                                  QLabel* label = new QLabel;
                                      label->setProperty("cssClass", QVariant::fromValue<QStringList>( QStringList() << "red" ) );
                                  

                                  and in the stylesheet:

                                  QLabel[cssClass~="red"] { color: red; }
                                  

                                  I don't what the equivalent of a QStringList in PyQt.

                                  J Offline
                                  J Offline
                                  JonB
                                  wrote on 15 Dec 2017, 13:26 last edited by JonB
                                  #23

                                  @raven-worx

                                  No, no need to change at runtime, all from startup.

                                  I assume what you have written actually does work for you?

                                  In Python (PyQt), we can't have QString, or QStringList, or QVariant :( (Don't ask, that's how it is...) PyQt's declaration of setProperty() is that it accepts Any, which means you pass any type from the language....

                                  Please, keeping it simple, no lists, would yours still work if you wrote:

                                  label->setProperty("cssClass", "red" );

                                  Or, if that does not work, what about:

                                  label->setProperty("cssClass", QVariant::fromValue<QString>( "red" ) );

                                  (And we could stick to = not ~= in the stylesheet. I'm trying to do everything with just one item, no lists, to get anything working here...)

                                  R 1 Reply Last reply 15 Dec 2017, 13:33
                                  0
                                  • J JonB
                                    15 Dec 2017, 13:26

                                    @raven-worx

                                    No, no need to change at runtime, all from startup.

                                    I assume what you have written actually does work for you?

                                    In Python (PyQt), we can't have QString, or QStringList, or QVariant :( (Don't ask, that's how it is...) PyQt's declaration of setProperty() is that it accepts Any, which means you pass any type from the language....

                                    Please, keeping it simple, no lists, would yours still work if you wrote:

                                    label->setProperty("cssClass", "red" );

                                    Or, if that does not work, what about:

                                    label->setProperty("cssClass", QVariant::fromValue<QString>( "red" ) );

                                    (And we could stick to = not ~= in the stylesheet. I'm trying to do everything with just one item, no lists, to get anything working here...)

                                    R Offline
                                    R Offline
                                    raven-worx
                                    Moderators
                                    wrote on 15 Dec 2017, 13:33 last edited by raven-worx
                                    #24

                                    @JNBarchan said in Qt Style Sheets cascading classes selectors:

                                    In Python (PyQt), we can't have QString, or QStringList, or QVariant :( (Don't ask, that's how it is...)

                                    This questions everything else then, if it is even possible at all.
                                    I have no idea then what exactly is assigned to the property in the background.

                                    Do you set the property before the widget is shown? Best would be to set the property right after instantiation.

                                    --- 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

                                    J 1 Reply Last reply 15 Dec 2017, 13:34
                                    0
                                    • R raven-worx
                                      15 Dec 2017, 13:33

                                      @JNBarchan said in Qt Style Sheets cascading classes selectors:

                                      In Python (PyQt), we can't have QString, or QStringList, or QVariant :( (Don't ask, that's how it is...)

                                      This questions everything else then, if it is even possible at all.
                                      I have no idea then what exactly is assigned to the property in the background.

                                      Do you set the property before the widget is shown? Best would be to set the property right after instantiation.

                                      J Offline
                                      J Offline
                                      JonB
                                      wrote on 15 Dec 2017, 13:34 last edited by JonB
                                      #25

                                      @raven-worx
                                      Please don't worry about that, I will sort out the PyQt side. I have just posted above what I need to know from you for C++, please. You are being so helpful I don't want to lose you...!

                                      P.S.
                                      Yes, I set property after instantiation, before it gets shown.

                                      R 1 Reply Last reply 15 Dec 2017, 13:39
                                      0
                                      • J JonB
                                        15 Dec 2017, 13:34

                                        @raven-worx
                                        Please don't worry about that, I will sort out the PyQt side. I have just posted above what I need to know from you for C++, please. You are being so helpful I don't want to lose you...!

                                        P.S.
                                        Yes, I set property after instantiation, before it gets shown.

                                        R Offline
                                        R Offline
                                        raven-worx
                                        Moderators
                                        wrote on 15 Dec 2017, 13:39 last edited by
                                        #26

                                        @JNBarchan
                                        for what you've posted so far the following should work (single strings in the property):

                                        Stylesheet:

                                        QLabel[cssClass="red"] { color: red; }
                                        

                                        Code:

                                        label.setProperty("cssClass", "red")
                                        

                                        --- 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

                                        J 1 Reply Last reply 15 Dec 2017, 13:50
                                        0
                                        • R raven-worx
                                          15 Dec 2017, 13:39

                                          @JNBarchan
                                          for what you've posted so far the following should work (single strings in the property):

                                          Stylesheet:

                                          QLabel[cssClass="red"] { color: red; }
                                          

                                          Code:

                                          label.setProperty("cssClass", "red")
                                          
                                          J Offline
                                          J Offline
                                          JonB
                                          wrote on 15 Dec 2017, 13:50 last edited by JonB
                                          #27

                                          @raven-worx
                                          I couldn't agree more that it should work, but that's what I claim to have in PyQt, and it does not :(

                                          I just put in, and checked in debugger:

                                          result = label.setProperty("cssclass", "red")
                                          

                                          and result is getting set to false. This corresponds correctly to:

                                          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.

                                          Then added immediately afterward:

                                          q = self.label.property("cssclass")

                                          and sure enough that is returning "red".

                                          So it looks to me that the property is getting set correctly...... It's the selector that doesn't seem to be matching, and I have tried using either = or ~=... And remember that QLabel { color: red; } does match...

                                          EDIT: And for an in-built property it does work correctly, e.g. QLabel[class="QLabel"] does match and QLabel[class="rubbish"] does not match. But not for a dynamic property I'm adding.

                                          You wrote:

                                          the following should work

                                          Very, very politely, have you actually verified that your code works?

                                          I confirm that I am finding: everything works fine when I use "inbuilt"/"known" properties (e.g. class, flat, etc.), but nothing works when I use use "dynamic" properties created on the fly via setProperty() (the property seems to get set OK on the QObject, but it's never matched by the selector). Anyone?

                                          UPDATE: OK, I'm starting from scratch in a minimal app, and it is working via setProperty(). Which is good :) So now, obviously, I'll report back after I've spent a few hundred hours finding out what's any different in my proper app... ;-)

                                          UPDATE2: I've now sorted out what was different in the app. (I'm sorry --- it's 32K-odd lines, I didn't write it, I don't know my way around all of it. I thought I knew what I was affecting with my test changes, I was affecting the wrong things.)

                                          The good news it's all working OK now, with setProperty()! Nothing special about Python/PyQt.

                                          I can even use multiple values for my properties, and the ~= selector matcher, and everything is as I need it to be. So you can build up your desired attributes (color, size, font, whatever) into loads of different rules in the CSS and combine them as you please on any widget :)

                                          @raven-worx
                                          You wrote:

                                          Altough i am surprised that it works when you assign a string with space-separated values instead of a QVariant containing a QStringList.

                                          Actually, it does seem to work quite happily as a space-separated string like "tall red rounded", treating each "word" as though it had been an element in the QStringList I guess. CSS/HTML/JavaScript works this way too with a space-separated list of class names.

                                          Thanks so much for your help & patience. And everyone else.

                                          R 1 Reply Last reply 15 Dec 2017, 21:41
                                          0

                                          17/29

                                          14 Dec 2017, 12:23

                                          • Login

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