Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. Stylesheet not applied correctly

Stylesheet not applied correctly

Scheduled Pinned Locked Moved Unsolved Qt for Python
16 Posts 4 Posters 2.4k Views
  • 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.
  • G Offline
    G Offline
    Gazi
    wrote on last edited by
    #1

    Hello,

    I have found out smth strange about how stylesheet is applied. I have prepared a minimal example, where I have a Drawer widget inside my main window.

    If I have the Drawer as a separate class, the style to it is not applied correctly. Here is a minimal example, where the Drawer should be red, but it is not:

    ################################################################
    import sys
    from PySide6.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QPushButton

    Sample stylesheet

    stylesheet = """
    QWidget#Drawer {
    background-color: red; /* Red background for the drawer */
    }
    """

    class Drawer(QWidget):
    def init(self):
    super().init()
    self.setObjectName('Drawer') # Set the object name for the drawer
    self.setStyleSheet(stylesheet) # Apply the stylesheet to the drawer

        # Create a vertical layout for the drawer
        layout = QVBoxLayout(self)
    
        # Add a button to the drawer
        button = QPushButton("Drawer Button")
        layout.addWidget(button)
    

    class MyWindow(QMainWindow):
    def init(self):
    super().init()
    self.init_ui()

    def init_ui(self):
        self.setWindowTitle("Minimal PySide6 Drawer Example")
    
        # Create a central widget
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
    
        # Create a vertical layout for the central widget
        layout = QVBoxLayout(central_widget)
    
        # Create the drawer widget and add it to the layout
        drawer_widget = Drawer()
        layout.addWidget(drawer_widget)
    

    def main():
    if not QApplication.instance():
    app = QApplication(sys.argv)
    else:
    app = QApplication.instance()

    # Apply the stylesheet
    app.setStyleSheet(stylesheet)
    
    window = MyWindow()
    window.show()
    sys.exit(app.exec())
    

    main()
    #################################################################

    Can anyone explain why the drawer is not set to red?

    Thank you.

    JonBJ 1 Reply Last reply
    0
    • G Gazi

      Hello,

      I have found out smth strange about how stylesheet is applied. I have prepared a minimal example, where I have a Drawer widget inside my main window.

      If I have the Drawer as a separate class, the style to it is not applied correctly. Here is a minimal example, where the Drawer should be red, but it is not:

      ################################################################
      import sys
      from PySide6.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QPushButton

      Sample stylesheet

      stylesheet = """
      QWidget#Drawer {
      background-color: red; /* Red background for the drawer */
      }
      """

      class Drawer(QWidget):
      def init(self):
      super().init()
      self.setObjectName('Drawer') # Set the object name for the drawer
      self.setStyleSheet(stylesheet) # Apply the stylesheet to the drawer

          # Create a vertical layout for the drawer
          layout = QVBoxLayout(self)
      
          # Add a button to the drawer
          button = QPushButton("Drawer Button")
          layout.addWidget(button)
      

      class MyWindow(QMainWindow):
      def init(self):
      super().init()
      self.init_ui()

      def init_ui(self):
          self.setWindowTitle("Minimal PySide6 Drawer Example")
      
          # Create a central widget
          central_widget = QWidget()
          self.setCentralWidget(central_widget)
      
          # Create a vertical layout for the central widget
          layout = QVBoxLayout(central_widget)
      
          # Create the drawer widget and add it to the layout
          drawer_widget = Drawer()
          layout.addWidget(drawer_widget)
      

      def main():
      if not QApplication.instance():
      app = QApplication(sys.argv)
      else:
      app = QApplication.instance()

      # Apply the stylesheet
      app.setStyleSheet(stylesheet)
      
      window = MyWindow()
      window.show()
      sys.exit(app.exec())
      

      main()
      #################################################################

      Can anyone explain why the drawer is not set to red?

      Thank you.

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

      @Gazi
      Please use Code tags (</> icon button) on blocks of code.

      Do either of #Drawer or Drawer work instead of QWidget#Drawer for selector?

      G 1 Reply Last reply
      0
      • JonBJ JonB

        @Gazi
        Please use Code tags (</> icon button) on blocks of code.

        Do either of #Drawer or Drawer work instead of QWidget#Drawer for selector?

        G Offline
        G Offline
        Gazi
        wrote on last edited by
        #3

        @JonB

        Thx for the reply.

        Neither #Drawer, nor Drawer work.

        Here is again the code:

        import sys
        from PySide6.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QPushButton
        
        # Sample stylesheet
        stylesheet = """
            QWidget#Drawer {
                background-color: red;  /* Red background for the drawer */
            }
        """
        
        class Drawer(QWidget):
            def __init__(self):
                super().__init__()
                self.setObjectName('Drawer')  # Set the object name for the drawer
                self.setStyleSheet(stylesheet)  # Apply the stylesheet to the drawer
                
                # Create a vertical layout for the drawer
                layout = QVBoxLayout(self)
        
                # Add a button to the drawer
                button = QPushButton("Drawer Button")
                layout.addWidget(button)
                
        
        class MyWindow(QMainWindow):
            def __init__(self):
                super().__init__()
        
                self.init_ui()
        
            def init_ui(self):
                self.setWindowTitle("Minimal PySide6 Drawer Example")
        
                # Create a central widget
                central_widget = QWidget()
                self.setCentralWidget(central_widget)
        
                # Create a vertical layout for the central widget
                layout = QVBoxLayout(central_widget)
        
                # Create the drawer widget and add it to the layout
                drawer_widget = Drawer()
                layout.addWidget(drawer_widget)
        
        def main():
            if not QApplication.instance():
                app = QApplication(sys.argv)
            else:
                app = QApplication.instance()    
                
            # Apply the stylesheet
            app.setStyleSheet(stylesheet)
            
            window = MyWindow()
            window.show()
            sys.exit(app.exec())
        
        main()
        
        
        SGaistS 1 Reply Last reply
        0
        • G Gazi

          @JonB

          Thx for the reply.

          Neither #Drawer, nor Drawer work.

          Here is again the code:

          import sys
          from PySide6.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QPushButton
          
          # Sample stylesheet
          stylesheet = """
              QWidget#Drawer {
                  background-color: red;  /* Red background for the drawer */
              }
          """
          
          class Drawer(QWidget):
              def __init__(self):
                  super().__init__()
                  self.setObjectName('Drawer')  # Set the object name for the drawer
                  self.setStyleSheet(stylesheet)  # Apply the stylesheet to the drawer
                  
                  # Create a vertical layout for the drawer
                  layout = QVBoxLayout(self)
          
                  # Add a button to the drawer
                  button = QPushButton("Drawer Button")
                  layout.addWidget(button)
                  
          
          class MyWindow(QMainWindow):
              def __init__(self):
                  super().__init__()
          
                  self.init_ui()
          
              def init_ui(self):
                  self.setWindowTitle("Minimal PySide6 Drawer Example")
          
                  # Create a central widget
                  central_widget = QWidget()
                  self.setCentralWidget(central_widget)
          
                  # Create a vertical layout for the central widget
                  layout = QVBoxLayout(central_widget)
          
                  # Create the drawer widget and add it to the layout
                  drawer_widget = Drawer()
                  layout.addWidget(drawer_widget)
          
          def main():
              if not QApplication.instance():
                  app = QApplication(sys.argv)
              else:
                  app = QApplication.instance()    
                  
              # Apply the stylesheet
              app.setStyleSheet(stylesheet)
              
              window = MyWindow()
              window.show()
              sys.exit(app.exec())
          
          main()
          
          
          SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          Hi,

          From memory, QWidget#Drawer applies to QWidget objects with an objectName set to Drawer. If you want to apply the stylesheet to widgets from the Drawer class, then just use Drawer.

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

          G 1 Reply Last reply
          1
          • SGaistS SGaist

            Hi,

            From memory, QWidget#Drawer applies to QWidget objects with an objectName set to Drawer. If you want to apply the stylesheet to widgets from the Drawer class, then just use Drawer.

            G Offline
            G Offline
            Gazi
            wrote on last edited by
            #5

            @SGaist

            If you mean to substitute "QWidget#Drawer" with "Drawer" in the stylesheet, then this does not work.

            SGaistS 1 Reply Last reply
            0
            • G Gazi

              @SGaist

              If you mean to substitute "QWidget#Drawer" with "Drawer" in the stylesheet, then this does not work.

              SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #6

              Looks like there's something off when putting your Drawer widget in your MyWindow. If you create and show a Draw instance in your main function, it works correctly.

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

              G 1 Reply Last reply
              0
              • SGaistS SGaist

                Looks like there's something off when putting your Drawer widget in your MyWindow. If you create and show a Draw instance in your main function, it works correctly.

                G Offline
                G Offline
                Gazi
                wrote on last edited by
                #7

                @SGaist

                You are right. When I do not have it as a separate class, but rather create it inside the main window, then it works perfectly. However, this is not the solution, because I have a much more complex app and I cannot have everything inside the main function.

                This is why I made this very minimal example so that the other can reproduce it and maybe someone can figure out what is going on there.

                JonBJ 2 Replies Last reply
                0
                • G Gazi

                  @SGaist

                  You are right. When I do not have it as a separate class, but rather create it inside the main window, then it works perfectly. However, this is not the solution, because I have a much more complex app and I cannot have everything inside the main function.

                  This is why I made this very minimal example so that the other can reproduce it and maybe someone can figure out what is going on there.

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

                  @Gazi
                  Just to let you know, I am presently playing with your code! I have Qt 5.15, not Qt 6. behaviour seems to be same (as expected).

                  Start by noticing that the following CSS selector does work for your pushbutton:

                  stylesheet = """
                      QWidget#Drawer QPushButton {
                          background-color: red;  /* Red background for the drawer */
                      }
                  """
                  

                  Once you specify a selector which names a class/instance (QWidget#Drawer) the rule applies directly to that class/instance (i.e. the Drawer) but does not cascade to its children (QPushButton). This is the root of your issue.

                  1 Reply Last reply
                  0
                  • G Gazi

                    @SGaist

                    You are right. When I do not have it as a separate class, but rather create it inside the main window, then it works perfectly. However, this is not the solution, because I have a much more complex app and I cannot have everything inside the main function.

                    This is why I made this very minimal example so that the other can reproduce it and maybe someone can figure out what is going on there.

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

                    @Gazi
                    I believe your issue may be because you are trying to inherit widget's color. I refer you to https://doc.qt.io/qtforpython-6/overviews/stylesheet-syntax.html#inheritance

                    In classic CSS, when font and color of an item is not explicitly set, it gets automatically inherited from the parent. By default, when using Qt Style Sheets, a widget does not automatically inherit its font and color setting from its parent widget.

                    Thus for your case I find the following (per the example there) does work:

                    stylesheet = """
                        QWidget#Drawer, QWidget#Drawer * {
                            background-color: red;  /* Red background for the drawer */
                        }
                    """
                    

                    Alternatively you can change to adding the QCoreApplication.setAttribute(Qt.AA_UseStyleSheetPropagationInWidgetStyles, True) statement to your program shown in that topic. (Note: I cannot test PySide6 but that statement may need adjusting I believe for PySide6, they moved all enumerated type values into their own classes, like https://doc.qt.io/qtforpython-6/PySide6/QtCore/Qt.html#PySide6.QtCore.PySide6.QtCore.Qt.ApplicationAttribute. I think you will need something which references Qt.ApplicationAttribute.AA_UseStyleSheetPropagationInWidgetStyles.) This would allow just QWidget#Drawer alone to work as the selector. But it would change the behaviour of all widgets' color inheritance.

                    Otherwise for your type case you just need to add the * all-children-selector to your rules explicitly.

                    The absolute truth? I find Qt's CSS stuff either confusing, inconsistent or hard to get to grips with. I found HTML's CSS easier to work with. I just play with Qt CSS rules till I get what works....

                    SGaistS 1 Reply Last reply
                    2
                    • JonBJ JonB

                      @Gazi
                      I believe your issue may be because you are trying to inherit widget's color. I refer you to https://doc.qt.io/qtforpython-6/overviews/stylesheet-syntax.html#inheritance

                      In classic CSS, when font and color of an item is not explicitly set, it gets automatically inherited from the parent. By default, when using Qt Style Sheets, a widget does not automatically inherit its font and color setting from its parent widget.

                      Thus for your case I find the following (per the example there) does work:

                      stylesheet = """
                          QWidget#Drawer, QWidget#Drawer * {
                              background-color: red;  /* Red background for the drawer */
                          }
                      """
                      

                      Alternatively you can change to adding the QCoreApplication.setAttribute(Qt.AA_UseStyleSheetPropagationInWidgetStyles, True) statement to your program shown in that topic. (Note: I cannot test PySide6 but that statement may need adjusting I believe for PySide6, they moved all enumerated type values into their own classes, like https://doc.qt.io/qtforpython-6/PySide6/QtCore/Qt.html#PySide6.QtCore.PySide6.QtCore.Qt.ApplicationAttribute. I think you will need something which references Qt.ApplicationAttribute.AA_UseStyleSheetPropagationInWidgetStyles.) This would allow just QWidget#Drawer alone to work as the selector. But it would change the behaviour of all widgets' color inheritance.

                      Otherwise for your type case you just need to add the * all-children-selector to your rules explicitly.

                      The absolute truth? I find Qt's CSS stuff either confusing, inconsistent or hard to get to grips with. I found HTML's CSS easier to work with. I just play with Qt CSS rules till I get what works....

                      SGaistS Offline
                      SGaistS Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on last edited by
                      #10

                      @JonB Nice catch ! I forgot about that one.

                      @Gazi out of curiosity, are you using one single stylesheet or one per widget ? If the latter, you could also directly apply the stylesheet without selector to these specific widgets.

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

                      G 1 Reply Last reply
                      0
                      • SGaistS SGaist

                        @JonB Nice catch ! I forgot about that one.

                        @Gazi out of curiosity, are you using one single stylesheet or one per widget ? If the latter, you could also directly apply the stylesheet without selector to these specific widgets.

                        G Offline
                        G Offline
                        Gazi
                        wrote on last edited by
                        #11

                        @SGaist I wanted to have a centralized stylesheet. However, it would be helpful for me if you could point out how to apply it per widget.

                        @JonB Thank you for your response. I tried it out and indeed when I use your code, it will make the drawer button red. However, what surprises me is that the drawer itself still does not get red. So, I added 2 buttons to the drawer to explain better. Only the buttons are red, not the drawer itself, as shown in the pic below:

                        da43e98a-c594-4efc-a5e0-1e479b229ae0-Screenshot from 2023-09-25 11-36-32.png file:///home/gazi/Pictures/Screenshots/Screenshot%20from%202023-09-25%2011-36-32.png

                        Here is the code:

                        import sys
                        from PySide6.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QPushButton
                        
                        # Sample stylesheet
                        stylesheet = """
                            QWidget#Drawer, QWidget#Drawer * {
                                background-color: red;  /* Red background for the drawer */
                            }
                        
                        """
                        
                        class Drawer(QWidget):
                            def __init__(self):
                                super().__init__()
                                self.setObjectName('Drawer')  # Set the object name for the drawer
                                
                                # Create a vertical layout for the drawer
                                layout = QVBoxLayout(self)
                        
                                # Add a button to the drawer
                                button1 = QPushButton("Drawer Button 1")
                                button2 = QPushButton("Drawer Button 2")
                                
                                layout.addWidget(button1)
                                layout.addStretch()
                                layout.addWidget(button2)
                                
                        
                        class MyWindow(QMainWindow):
                            def __init__(self):
                                super().__init__()
                        
                                self.init_ui()
                        
                            def init_ui(self):
                                self.setWindowTitle("Minimal PySide6 Drawer Example")
                        
                                # Create a central widget
                                central_widget = QWidget()
                                self.setCentralWidget(central_widget)
                        
                                # Create a vertical layout for the central widget
                                layout = QVBoxLayout(central_widget)
                        
                                # Create the drawer widget and add it to the layout
                                drawer_widget = Drawer()
                                layout.addWidget(drawer_widget)
                        
                        def main():
                            if not QApplication.instance():
                                app = QApplication(sys.argv)
                            else:
                                app = QApplication.instance()    
                                
                            # Apply the stylesheet
                            app.setStyleSheet(stylesheet)
                            
                            window = MyWindow()
                            window.show()
                            sys.exit(app.exec())
                        
                        main()
                        
                        

                        Shouldn't the entire Drawer widget be red?

                        Thanks a lot for the support.

                        JonBJ 1 Reply Last reply
                        0
                        • G Gazi

                          @SGaist I wanted to have a centralized stylesheet. However, it would be helpful for me if you could point out how to apply it per widget.

                          @JonB Thank you for your response. I tried it out and indeed when I use your code, it will make the drawer button red. However, what surprises me is that the drawer itself still does not get red. So, I added 2 buttons to the drawer to explain better. Only the buttons are red, not the drawer itself, as shown in the pic below:

                          da43e98a-c594-4efc-a5e0-1e479b229ae0-Screenshot from 2023-09-25 11-36-32.png file:///home/gazi/Pictures/Screenshots/Screenshot%20from%202023-09-25%2011-36-32.png

                          Here is the code:

                          import sys
                          from PySide6.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QPushButton
                          
                          # Sample stylesheet
                          stylesheet = """
                              QWidget#Drawer, QWidget#Drawer * {
                                  background-color: red;  /* Red background for the drawer */
                              }
                          
                          """
                          
                          class Drawer(QWidget):
                              def __init__(self):
                                  super().__init__()
                                  self.setObjectName('Drawer')  # Set the object name for the drawer
                                  
                                  # Create a vertical layout for the drawer
                                  layout = QVBoxLayout(self)
                          
                                  # Add a button to the drawer
                                  button1 = QPushButton("Drawer Button 1")
                                  button2 = QPushButton("Drawer Button 2")
                                  
                                  layout.addWidget(button1)
                                  layout.addStretch()
                                  layout.addWidget(button2)
                                  
                          
                          class MyWindow(QMainWindow):
                              def __init__(self):
                                  super().__init__()
                          
                                  self.init_ui()
                          
                              def init_ui(self):
                                  self.setWindowTitle("Minimal PySide6 Drawer Example")
                          
                                  # Create a central widget
                                  central_widget = QWidget()
                                  self.setCentralWidget(central_widget)
                          
                                  # Create a vertical layout for the central widget
                                  layout = QVBoxLayout(central_widget)
                          
                                  # Create the drawer widget and add it to the layout
                                  drawer_widget = Drawer()
                                  layout.addWidget(drawer_widget)
                          
                          def main():
                              if not QApplication.instance():
                                  app = QApplication(sys.argv)
                              else:
                                  app = QApplication.instance()    
                                  
                              # Apply the stylesheet
                              app.setStyleSheet(stylesheet)
                              
                              window = MyWindow()
                              window.show()
                              sys.exit(app.exec())
                          
                          main()
                          
                          

                          Shouldn't the entire Drawer widget be red?

                          Thanks a lot for the support.

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

                          @Gazi
                          The drawer QWidget itself is not red because of https://doc.qt.io/qtforpython-6/overviews/stylesheet-reference.html#list-of-stylable-widgets, QWidget item:

                          Supports only the background , background-clip and background-origin properties.
                          If you subclass from QWidget , you need to provide a paintEvent for your custom QWidget as below:

                          If you want that, in your Drawer class you need (tested under my PySide2/Qt5):

                          from PySide2.QtWidgets import ..., QStyle, QStyleOption
                          from PySide2.QtGui import QPainter
                          
                          class Drawer(QWidget):
                              def paintEvent(self, arg__0):
                                  opt = QStyleOption()
                                  opt.initFrom(self)
                                  p = QPainter(self)
                                  self.style().drawPrimitive(QStyle.PE_Widget, opt, p, self)
                          
                          G 1 Reply Last reply
                          3
                          • JonBJ JonB

                            @Gazi
                            The drawer QWidget itself is not red because of https://doc.qt.io/qtforpython-6/overviews/stylesheet-reference.html#list-of-stylable-widgets, QWidget item:

                            Supports only the background , background-clip and background-origin properties.
                            If you subclass from QWidget , you need to provide a paintEvent for your custom QWidget as below:

                            If you want that, in your Drawer class you need (tested under my PySide2/Qt5):

                            from PySide2.QtWidgets import ..., QStyle, QStyleOption
                            from PySide2.QtGui import QPainter
                            
                            class Drawer(QWidget):
                                def paintEvent(self, arg__0):
                                    opt = QStyleOption()
                                    opt.initFrom(self)
                                    p = QPainter(self)
                                    self.style().drawPrimitive(QStyle.PE_Widget, opt, p, self)
                            
                            G Offline
                            G Offline
                            Gazi
                            wrote on last edited by
                            #13

                            @JonB Thx for pointing it out. Still i have a lot of trouble to understand why they made it so complicated. I don't know if there are many people who find it complicated, but i guess it would be much more convenient to have some styling capabilities as one has in react-native.

                            1 Reply Last reply
                            0
                            • G Offline
                              G Offline
                              Gazi
                              wrote on last edited by
                              #14

                              @JonB And one more thing, is there a way to specify that i do not want my child widgets to take the style of the parent? That would solve quite some things.

                              SGaistS 1 Reply Last reply
                              0
                              • G Gazi

                                @JonB And one more thing, is there a way to specify that i do not want my child widgets to take the style of the parent? That would solve quite some things.

                                SGaistS Offline
                                SGaistS Offline
                                SGaist
                                Lifetime Qt Champion
                                wrote on last edited by
                                #15

                                @Gazi depending on the result you are after, this article from KDAB about QStyle VS stylesheet might be of interest.

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

                                1 Reply Last reply
                                0
                                • J Offline
                                  J Offline
                                  jcyrss
                                  wrote on last edited by
                                  #16

                                  QSS has too much exceptional rules, which makes it hard to use. Hope it could be simplified.

                                  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