【问题标题】:PyQt - How to use the "setStyleSheet" method properly?PyQt - 如何正确使用“setStyleSheet”方法?
【发布时间】:2021-04-23 04:50:27
【问题描述】:

如果我使用setStyleSheet 方法来更改特定小部件的样式,则放置在其中的其他小部件会更改其样式,但我不想要它!我可以举两个例子:

当我更改框架的边框/背景颜色时(查看放置在其中的小部件):

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_())

或者当我更改树视图小部件的边框颜色时(滚动的树视图小部件变为白色):

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_())

我的问题是,如何在不修改其他小部件的样式的情况下更改特定小部件的样式?

########### 更新:

在我的第一个示例中,如果我不使用指令self.treeview.setStyleSheet("border: 1px solid; border-color:red"),我意识到进度条小部件不会像以前那样展开。看这个截图:

有什么问题?

【问题讨论】:

    标签: python pyqt styles


    【解决方案1】:

    我强烈建议您更仔细地阅读 style sheet syntaxreference 文档,因为那里的所有内容都明确指定和解释:

    样式表由一系列样式规则组成。样式规则由选择器和声明组成。 选择器 指定哪些小部件受规则影响; 声明指定应该在小部件上设置哪些属性。

    根据定义,样式表是级联的

    小部件上设置的样式表在其子代上传播,这些子代继承父代的样式。

    如果你像这样设置一个通用属性:

    border: 1px solid black;
    

    结果是 all 它的子元素将具有该边框:您只给出了 声明 但没有 选择器,所以一个 universal 选择器被用作隐式。

    这不仅仅是 Qt,这是典型的 CSS(QSS 从中获取主要概念),它的工作原理与任何其他小部件的 样式 属性完全相同:在小部件,将它们传播给它的所有子级。
    不同之处在于样式表(与标准 CSS 完全一样)可以使用 selectors

    如果您只想设置树小部件的样式,请使用该类选择器:

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

    【讨论】:

    • 在我的第一个示例中,我在另一个框架内有一个框架。我有两个问题。如果我只想更改第一帧的样式,那么正确的选择器是什么?如果我使用指令self.frame1.setStyleSheet("QFrame{border: 1px solid; border-color:red; background-color:white}") 选择器QFrame 会影响它们两者。第二个问题是,为什么如果我不使用指令self.frame1.setStyleSheet(..) self.ProgressBar 小部件不会在指定的布局(self.frame2layout)之后展开?右边有个空格..
    • 第一个答案是:正确使用选择器。例如,当您使用相同的基类时,请使用#objectName 选择器(self.frame1.setObjectName('topFrame') 然后QFrame#topFrame {...}。我不明白您的第二个问题,您只在右侧看到一个空格,而不是在离开了吗?
    • 感谢musicamente的回复,现在我明白了。对于我的第二个问题,我附上了一张图片并更新了我的主题。让我知道。
    • 如果我使用以下说明仅更改两个框架的样式,我会遇到同样的问题:self.frame1.setObjectName('topFrame')self.frame1.setStyleSheet("QFrame#topFrame{border: 1px solid; border-color:red; background-color:white}") self.frame2.setObjectName('xx')``self.frame2.setStyleSheet("QFrame#xx{border: 1px solid; border-color:blue; background-color:white}")
    • 我已经使用了您的第一个代码 sn-p 并将上面的行添加到 __init__ 的末尾,但我没有看到这种行为。我建议您也这样做(从帖子中获取代码,不要尝试根据您计算机上的内容进行调整!)并检查结果。如果我们不确定我们使用的是相同的代码,我们就无法比较代码。请注意,调用 self.frame1.setStyleSheet 会自动覆盖之前在同一个小部件上设置的任何内容,因此您是否评论了第一行 setStyleSheet 并不重要。
    猜你喜欢
    • 2013-05-28
    • 1970-01-01
    • 2021-06-03
    • 2011-02-07
    • 1970-01-01
    • 2014-03-28
    • 2014-09-26
    • 1970-01-01
    • 2016-11-20
    相关资源
    最近更新 更多