布局中小部件的哪个样式表选择器?
Posted
技术标签:
【中文标题】布局中小部件的哪个样式表选择器?【英文标题】:Which style sheet selector for widgets in a layout? 【发布时间】:2018-03-14 14:26:31 【问题描述】:假设我们有一个QFormLayout
,其中objectName
设置为"formLayout"
。
此布局由两个QLabel
和QLineEdit
和对象组成:
formLayout = QtGui.QFormLayout()
formLayout.setObjectName("formLayout")
label1 = QtGui.QLabel()
label2 = QtGui.QLabel()
lineEdit1 = QtGui.QLineEdit()
lineEdit2 = QtGui.QLineEdit()
formLayout.addRow(label1, lineEdit1)
formLayout.addRow(label2, lineEdit2)
现在我想用外部.qss
文件更改formLayout
中QLabel
's/QLineEdit
's 的样式。我希望是这样的:
QFormLayout#formLayout > QLabel, QLineEdit
/*set some styles for QLabel/QLineEdit in the formLayout*/
不幸的是,这不起作用。我知道我可以将formLayout
中的所有QLabel
设置为相同的对象名称:
label1 = QtGui.setObjectName("formLayoutLabel")
label2 = QtGui.setObjectName("formLayoutLabel")
并像这样设置他们的风格:
QLabel#formLayoutLabel
/*set some styles for QLabel in the formLayout*/
我的问题:
如何在不使用对象的情况下更改位于外部 .qss
中的父布局/小部件(例如 formLayout
)中特定类型的所有小部件(例如 QLabel
和 QLineEdit
)的样式命名属性?
【问题讨论】:
所有布局必须有一个父级,并且该布局内的所有小部件都将自动重新设置为其父级。因此,只需为布局的父级指定一个对象名称,然后在您的全局样式表中您可以使用#formParent QLabel ...
等。有关其他选项,请参阅:Stylesheet Selector Types。
在我的例子中,层次结构看起来像这样:QDialog -> QVBoxLayout-> QHBoxLayout -> QFormLayout
。所以所有布局的父级是QDialog
对吗?为了只修改表单布局的组件,我必须为其添加一个容器小部件,这将导致:QDialog -> QVBoxLayout-> QHBoxLayout -> QWidget -> QFormLayout
。我已经对此进行了测试,并且可以正常工作。这是最好的解决方案,还是没有“帮助容器小部件”我可以做得更好。
另一个问题:这种方法是最佳实践吗?或者它们是否应该与上面示例中提到的对象名称相同。基本上:通过相同的父对象与相同的对象名称修改 QWidgets 的样式?
我认为没有任何一种“最佳”解决方案。您只需要选择最适合您当前正在开发的应用程序上下文的一个即可。
【参考方案1】:
QLayout
派生类不是QWidget
派生的,这将它们完全排除在 Qt 样式系统之外。
解决此问题的一种方法是使用小部件支持每个布局,即不要让小部件具有多个布局。这样,属于布局的所有小部件(即标签)也是同一个小部件的子级,您可以在其中注入样式表:
QLabel
/*set some styles for QLabel in the formLayout*/
因此,如果您有一个具有四个布局的小部件,您应该在其中放置四个子小部件,并将每个布局放在其中一个内(然后按照您之前排列布局的方式布置小部件)。
另一种解决方法是对小部件进行子类化,并在样式表中按类型名称选择它们。例如,如果您在布局中有 特殊 标签,请使用最简单的QLabel
子类:
class Layout1Label(QtGui.QLabel):
def __init__(self, parent=None):
super(Layout1Label, self).__init__(parent)
然后只在布局中添加该类型的标签:
label = Layout1Label()
layout.addWidget(label)
并在样式表中引用它们:
Layout1Label
/*set some styles for all labels in layout*/
这应该是有效的,但可能会变得乏味并且需要付出很多努力(您最终可能会得到很多类型,仅用于样式表选择)。
【讨论】:
一个小部件不可能有多个布局。同样,所有布局都必须有一个父级(否则它们包含的小部件不会被布局出来)。布局内的任何小部件都将自动重新设置为布局所设置的任何小部件。因此,布局(及其子布局)中的所有小部件将形成自然层次结构。如果这不是真的。嵌套布局不可能工作,级联样式表也是如此。由此也得出结论,一个小部件不可能属于多个布局。 对不起,一定是文字问题。我的意思是一个小部件可以包含多个布局,而不是小部件自己的布局。使用有关布局的子/父关系术语也可能会产生误导,因为它们不是 Qwidget 子类。 一点也不误导。所有布局类都继承 QObject,所有小部件子类也是如此。所以他们最强调确实形成子/父关系。正如我上面所说,如果不是这样,布局和 qss 就不可能工作。对象层次结构是绝对必要的:这就是为什么布局内的所有小部件都会自动重新设置父级。 它在样式的上下文中具有误导性:是的,有父对象和子对象,但其中一些参与 样式层次结构(小部件),而另一些则不参与(布局)。以上是关于布局中小部件的哪个样式表选择器?的主要内容,如果未能解决你的问题,请参考以下文章