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
Forum Updated to NodeBB v4.3 + New Features

Stylesheet not applied correctly

Scheduled Pinned Locked Moved Unsolved Qt for Python
16 Posts 4 Posters 3.5k 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.
  • 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