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. Setting QObject properties through Qt CSS not fully working
Forum Updated to NodeBB v4.3 + New Features

Setting QObject properties through Qt CSS not fully working

Scheduled Pinned Locked Moved Solved General and Desktop
8 Posts 3 Posters 2.8k Views 1 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.
  • napajejenunedk0N Offline
    napajejenunedk0N Offline
    napajejenunedk0
    wrote on last edited by
    #1

    Hello, all.

    I have the following sample code:

    #include <QApplication>
    #include <QLabel>
    #include <QTimer>
    
    int main( int argc, char* argv[] )
    {
        QApplication a( argc, argv );
        QLabel label;
        label.setStyleSheet(
                    "QLabel {\n"
                    "    border: 2px solid green;\n"
                    "    qproperty-pixmap: url(:/Green.png);\n"
                    "}\n"
                    "\n"
                    "QLabel:disabled {\n"
                    "    border: 2px solid gray;\n"
                    "    qproperty-pixmap: url(:/Gray.png);\n"
                    "}" );
    
        QTimer t;
        QTimer::connect( & t,
                         & QTimer::timeout,
                         [ & label ]()
                         {
                             label.setEnabled( ! label.isEnabled() );
                         } );
        label.show();
        t.start( 1500 );
    
        return a.exec();
    }
    

    The stylesheet is successfully applied for both the border standard CSS property and the QLabel's custom "pixmap" property one and for both states. In my actual application setting the value of a custom property through CSS using the "qproperty-" syntax works but what fails is to give the custom property at hand a different value for another state of the QObject-based instance at hand. Tested whether there is a difference between setting the CSS directly to the QObject-based instance at hand or to the QApplication's stylesheet and found there's none. Removed the whole CSS of my application and left only that of the given QObject-based instance at hand and again the QObject's instance property was set only with the value provided for its default state but not for its disabled state for example. The QObject-based instance is again QLabel and again I want to set its "pixmap" property.

    Can't provide a more concrete and deep example, but just want to know whether anyone has stumbled upon such problem in his/her real-life application and if so did he/she found any solution. Can't see why setting a QObject's custom property through CSS for more than one state of the QObject-based instance could fail in one and succeed in another application.

    raven-worxR 1 Reply Last reply
    0
    • napajejenunedk0N napajejenunedk0

      Hello, all.

      I have the following sample code:

      #include <QApplication>
      #include <QLabel>
      #include <QTimer>
      
      int main( int argc, char* argv[] )
      {
          QApplication a( argc, argv );
          QLabel label;
          label.setStyleSheet(
                      "QLabel {\n"
                      "    border: 2px solid green;\n"
                      "    qproperty-pixmap: url(:/Green.png);\n"
                      "}\n"
                      "\n"
                      "QLabel:disabled {\n"
                      "    border: 2px solid gray;\n"
                      "    qproperty-pixmap: url(:/Gray.png);\n"
                      "}" );
      
          QTimer t;
          QTimer::connect( & t,
                           & QTimer::timeout,
                           [ & label ]()
                           {
                               label.setEnabled( ! label.isEnabled() );
                           } );
          label.show();
          t.start( 1500 );
      
          return a.exec();
      }
      

      The stylesheet is successfully applied for both the border standard CSS property and the QLabel's custom "pixmap" property one and for both states. In my actual application setting the value of a custom property through CSS using the "qproperty-" syntax works but what fails is to give the custom property at hand a different value for another state of the QObject-based instance at hand. Tested whether there is a difference between setting the CSS directly to the QObject-based instance at hand or to the QApplication's stylesheet and found there's none. Removed the whole CSS of my application and left only that of the given QObject-based instance at hand and again the QObject's instance property was set only with the value provided for its default state but not for its disabled state for example. The QObject-based instance is again QLabel and again I want to set its "pixmap" property.

      Can't provide a more concrete and deep example, but just want to know whether anyone has stumbled upon such problem in his/her real-life application and if so did he/she found any solution. Can't see why setting a QObject's custom property through CSS for more than one state of the QObject-based instance could fail in one and succeed in another application.

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

      @napajejenunedk0 said in Setting QObject properties through Qt CSS not fully working:

      QLabel:disabled {\n"
      " border: 2px solid gray;\n"
      " qproperty-pixmap: url(:/Gray.png);\n"
      "}"

      properties are not reapplied on pseudo state changes. See QTBUG-2982, as you can see it is very old, and i wouldn't expect it to be fixed any time soon.

      What happens when you do this:

      QTimer::connect( & t,
                           & QTimer::timeout,
                           [ & label ]()
                           {
                               label.setEnabled( ! label.isEnabled() );
                               label.style()->polish(&label);
                           } );
      

      --- 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
      1
      • napajejenunedk0N Offline
        napajejenunedk0N Offline
        napajejenunedk0
        wrote on last edited by
        #3

        What happens when you do this: ...

        Nothing. What I know is that repolishing of a QWidget-based class instance is needed only in case its stylesheet depends on values of dynamic object properties, not in case of using CSS or Qt CSS-specific integrated pseudo states. Already tried repolishing the QLabel but nothing helped.

        properties are not reapplied on pseudo state changes. See QTBUG-2982, as you can see it is very old, and i wouldn't expect it to be fixed any time soon.

        Using Qt 5.5.1 MSVC 12 (VS 2013) 32-bit and looking both at the test project, where it works, and another real-world one, where it doesn't it is actually partially reproducible. As mentioned in my original post, it is strange that removing the whole stylesheet of the actual application (not the test one) and leaving only that of the QLabel at hand doesn't make any difference. I was thinking of removing all object names if they are in some way staying in the way of the correct application of the stylesheet. Another reason could be the actual project's UI complexity.

        1 Reply Last reply
        0
        • napajejenunedk0N Offline
          napajejenunedk0N Offline
          napajejenunedk0
          wrote on last edited by
          #4

          @raven-worx, replaced the QLabel with QPushButton, since I want to control its icon as well through CSS (as it is the case in the Qt bug you've cited above) and saw that trying to set different icon (qproperty-icon) according to its :checked pseudo state results in applying only one of the provided icons. Unpolishing and polishing the QPushButton while using the pseudo state has no effect. Moving to dynamic properties or more properly said to the dynamic property equivalent of the given pseudo state - :checked to [checked="true"] plus repolishing the button upon a change in its checked state resulted in the desired behavior. For sure this semi-automaticity is not the best programming practice. Setting the topic to solved despite the usage of a workaround.

          raven-worxR 1 Reply Last reply
          0
          • napajejenunedk0N napajejenunedk0

            @raven-worx, replaced the QLabel with QPushButton, since I want to control its icon as well through CSS (as it is the case in the Qt bug you've cited above) and saw that trying to set different icon (qproperty-icon) according to its :checked pseudo state results in applying only one of the provided icons. Unpolishing and polishing the QPushButton while using the pseudo state has no effect. Moving to dynamic properties or more properly said to the dynamic property equivalent of the given pseudo state - :checked to [checked="true"] plus repolishing the button upon a change in its checked state resulted in the desired behavior. For sure this semi-automaticity is not the best programming practice. Setting the topic to solved despite the usage of a workaround.

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

            @napajejenunedk0
            yes, QSS by far is not perfect and has many internal bugs.

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

              @napajejenunedk0
              yes, QSS by far is not perfect and has many internal bugs.

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

              @raven-worx said in Setting QObject properties through Qt CSS not fully working:

              @napajejenunedk0
              yes, QSS by far is not perfect and has many internal bugs.

              This statement is a bit scary, given that I have recently changed all the existing "in-line" code (i.e. native Qt widget calls) over to using stylesheets everywhere... :(

              raven-worxR 1 Reply Last reply
              0
              • JonBJ JonB

                @raven-worx said in Setting QObject properties through Qt CSS not fully working:

                @napajejenunedk0
                yes, QSS by far is not perfect and has many internal bugs.

                This statement is a bit scary, given that I have recently changed all the existing "in-line" code (i.e. native Qt widget calls) over to using stylesheets everywhere... :(

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

                @JonB
                Sorry, but thats how it is.
                It of course depends on how extensively you are using QSS. In general it does it's job well, but there are some annoying special cases i already encountered over the years.
                And since QSS mostly fails silently they are hard to debug.

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

                  @JonB
                  Sorry, but thats how it is.
                  It of course depends on how extensively you are using QSS. In general it does it's job well, but there are some annoying special cases i already encountered over the years.
                  And since QSS mostly fails silently they are hard to debug.

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

                  @raven-worx
                  Still scary!! :)
                  I am now using QSS everywhere, like I would use just CSS for all my HTML/CSS styling.

                  And since QSS mostly fails silently they are hard to debug.

                  Couldn't agree more! It seems to use qDebug() for any problems, and doesn't even return error codes. Already faced this, for the record (others might wish to copy) as a consequence when reading my application stylesheets the code I use is along the following lines:

                  def readStylesheets():
                      hdlr = errfunctions.addQtMessageDialogHandler()
                      try:
                          QtWidgets.QApplication.instance().setStyleSheet(css)
                      finally:
                          errfunctions.removeQtMessageDialogHandler(hdlr)
                  
                  def addQtMessageDialogHandler() -> LoggingDialogHandler:
                      # Add a LoggingDialogHandler to when qtMessageHandler() (which uses qtLogger) is called
                      hdlr = LoggingDialogHandler()
                      qtLogger.addHandler(hdlr)
                      return hdlr
                  
                  def removeQtMessageDialogHandler(hdlr: LoggingDialogHandler):
                      # Remove a LoggingDialogHandler previously added via addQtMessageDialogHandler()
                      qtLogger.removeHandler(hdlr)
                  
                  def qtMessageHandler(type: QtCore.QtMsgType, context: QtCore.QMessageLogContext, msg: str):
                      # Message handler for Qt qDebug() etc.
                      # see https://evileg.com/en/post/154/,
                      # https://stackoverflow.com/questions/35894171/redirect-qdebug-output-to-file-with-pyqt5,
                      # http://thispageintentionally.blogspot.co.uk/2014/03/trapping-qt-log-messages.html
                      ...
                  
                  
                  # install qtMessageHandler() to handle qDebug() etc.
                  QtCore.qInstallMessageHandler(qtMessageHandler)
                  
                  

                  i.e. the gist here is I have a global qtMessageHandler() function defined --- which is what qDebug() etc. all call --- and installed via QtCore.qInstallMessageHandler(), so I can see all debug errors/warnings. And when I'm about to read a QSS stylesheet, I wrap the reading code so that it throws up an actual "error dialog" (or whatever you want) if any qDebug() is executed by the Qt reading code, as the only way to clearly see if there has been any kind of error.

                  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