'PyQt - How to use the "setStyleSheet" method properly?

if I use the setStyleSheet method in order to change the style for a specific widget, the other ones placed inside it, changes their style, but I don't want it! I can bring you two example:

when I change the border/background color for a frame (see the widgets placed inside it):

import PyQt5.QtGui as qtg
import PyQt5.QtCore as qtc
import PyQt5.QtWidgets as qtw
import sys

class MainWindow(qtw.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
 
        self.resize(520,300)
        self.setWindowTitle("Treeview Example")

        self.layout = qtw.QVBoxLayout()

        self.frame1=qtw.QFrame()
        self.frame1layout=qtw.QVBoxLayout()
        self.frame1layout.setContentsMargins(5, 5, 5, 5)
        self.frame1.setLayout(self.frame1layout)
        self.frame1.setStyleSheet("border: 1px solid; border-color:red; background-color:white") # I change the style for the main frame
        self.layout.addWidget(self.frame1)
        
        self.frame2=qtw.QFrame()
        self.frame2layout=qtw.QVBoxLayout()
        self.frame2layout.setContentsMargins(10, 10, 10, 10)
        self.frame2.setLayout(self.frame2layout)
        
        self.frame1layout.addWidget(self.frame2)
        self.ProgressBar=qtw.QProgressBar()
        self.frame2layout.addWidget(self.ProgressBar)

        self.setLayout(self.layout)
 
if __name__ == '__main__':
    app = qtw.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

enter image description here

or when I change the border color for a treeview widget (the scrolled treeview widget is became white):

import PyQt5.QtGui as qtg
import PyQt5.QtCore as qtc
import PyQt5.QtWidgets as qtw
import sys

class MainWindow(qtw.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
 
        self.resize(520,300)
        self.setWindowTitle("Treeview Example")

        self.layout = qtw.QVBoxLayout()

        self.treeview = qtw.QTreeView(self)
        self.treeview.setStyleSheet("border: 1px solid; border-color:red") # it destroy the style of the objects inside the treeview widget!
        model = qtg.QStandardItemModel()
        rootNode = model.invisibleRootItem()
        
        section1 = qtg.QStandardItem("A")
        section1.appendRow([qtg.QStandardItem("A1")])
        childnode = qtg.QStandardItem("A2")
        section1.appendRow([childnode])
         
        section2 = qtg.QStandardItem("B")
        section2.appendRow([qtg.QStandardItem("B1")])
        section2.appendRow([qtg.QStandardItem("B2")])
        
        rootNode.appendRow([section1])
        rootNode.appendRow([section2])
        
        self.treeview.setHeaderHidden(True)
        
        self.treeview.setModel(model)
        
        self.layout.addWidget(self.treeview)
        self.setLayout(self.layout)
 
if __name__ == '__main__':
    app = qtw.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

enter image description here

my question is, how can I change the style of a specific widget without modifying the style of the other ones?

########### UPDATE:

in my first example, if I don't use the instruction self.treeview.setStyleSheet("border: 1px solid; border-color:red") I realized that the progress bar widget doesn't expand as before. see this screenshot: enter image description here

what is the issue?



Solution 1:[1]

I strongly suggest you to more carefully read the style sheet syntax and reference documentation, as everything is clearly specified and explained there:

Style sheets consist of a sequence of style rules. A style rule is made up of a selector and a declaration. The selector specifies which widgets are affected by the rule; the declaration specifies which properties should be set on the widget.

Stylesheets are, by definition, cascading.

The stylesheet set on a widget is propagated on its children, those children inherit the style of the parent.

If you set a generic property like this:

border: 1px solid black;

The result is that all its children will have that border: you only gave the declaration but without the selector, so a universal selector is used as implicit.

This is not just Qt, this is typical of CSS (from which QSS take their main concepts), and it works exactly as any other widget styling property: setting a font or a palette on a widget, propagates them to all its children.
The difference is that with stylesheets (exactly like standard CSS) you can use selectors.

If you want to style the tree widget only, then use that class selector:

    self.treeview.setStyleSheet('''
            QTreeView {
                border: 1px solid; 
                border-color:red;
            }
    ''')

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 musicamante