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.
  • 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
    • 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 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?

      raven-worxR 1 Reply Last reply
      0
      • JonBJ JonB

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

        raven-worxR Offline
        raven-worxR Offline
        raven-worx
        Moderators
        wrote on 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

        JonBJ 1 Reply Last reply
        1
        • raven-worxR raven-worx

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

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on 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...)

          raven-worxR 1 Reply Last reply
          0
          • JonBJ JonB

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

            raven-worxR Offline
            raven-worxR Offline
            raven-worx
            Moderators
            wrote on 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

            JonBJ 1 Reply Last reply
            0
            • raven-worxR raven-worx

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

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on 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.

              raven-worxR 1 Reply Last reply
              0
              • JonBJ JonB

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

                raven-worxR Offline
                raven-worxR Offline
                raven-worx
                Moderators
                wrote on 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

                JonBJ 1 Reply Last reply
                0
                • raven-worxR raven-worx

                  @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")
                  
                  JonBJ Offline
                  JonBJ Offline
                  JonB
                  wrote on 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.

                  raven-worxR 1 Reply Last reply
                  0
                  • JonBJ JonB

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

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

                    @JNBarchan said in Qt Style Sheets cascading classes selectors:

                    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.

                    yes CSS does work this way. But Qt stylesheets (QSS) just have taken over the basic syntax of CSS2. Everything behind it is completely unrelated to CSS.

                    Glad you figured out your issue.

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

                    1 Reply Last reply
                    0
                    • 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

                      • Login

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