装饰小工具应用程序#

QtWidgets应用程序使用默认主题,该主题取决于平台。在某些情况下,系统级别的配置会修改Qt主题,导致应用程序以不同的方式显示。

但您可以照顾自己的控件,并为每个组件提供自定义样式。例如,查看以下简单示例:

import sys
from PySide6.QtCore import Qt
from PySide6.QtWidgets import QApplication, QLabel

if __name__ == "__main__":
    app = QApplication()
    w = QLabel("This is a placeholder text")
    w.setAlignment(Qt.AlignCenter)
    w.show()
    sys.exit(app.exec())

执行此代码后,您将看到一个居中的简单QLabel,并包含占位符文本。

Simple Widget with no style

您可以使用类似CSS的语法来装饰您的应用程序。更多信息,请参阅Qt样式表参考

通过设置一些CSS属性,例如background-colorfont-family,可以以不同方式对QLabel进行装饰,让我们看看代码是如何变化的

import sys
from PySide6.QtCore import Qt
from PySide6.QtWidgets import QApplication, QLabel

if __name__ == "__main__":
    app = QApplication()
    w = QLabel("This is a placeholder text")
    w.setAlignment(Qt.AlignCenter)
    w.setStyleSheet("""
        background-color: #262626;
        color: #FFFFFF;
        font-family: Titillium;
        font-size: 18px;
        """)
    w.show()
    sys.exit(app.exec())

现在运行代码时,请注意QLabel的外观已经与您的自定义样式不同

Simple Widget with Style

注意

如果您没有安装字体Titillium,可以尝试使用您喜欢的任何其他字体。请记住,您可以使用QFontDatabase列出您的已安装字体,具体来说,是families()方法。

像上一个示例那样单独装饰每个UI元素是一个很繁琐的过程。这个更简单的解决方案是使用Qt样式表,它是一或多个定义应用程序中UI元素样式的.qss文件。

更多信息可以在Qt样式表示例文档页面上找到。

Qt样式表#

警告

在开始修改应用程序之前,请记住,您将负责所有应用程序的图形细节。修改边距和大小可能会导致看起来奇怪或不正确,因此在修改样式时需要小心。建议创建一个全新的 Qt 风格来覆盖所有可能的边缘情况。

qss 文件与 CSS 文件非常相似,但您需要指定 Widget 组件,可选地指定对象名称。

QLabel {
    background-color: red;
}

QLabel#title {
    font-size: 20px;
}

第一种样式定义了您的应用程序中所有 QLabel 对象的 background-color,而第二种样式仅针对 title 对象进行样式定义。

注意

您可以使用 setObjectName(str) 函数为任何 Qt 对象设置对象名称,例如:对于 label = QLabel(“Test”),您可以编写 label.setObjectName(“title”)

一旦您的应用程序有了 qss 文件,您可以通过读取文件并使用 QApplication.setStyleSheet(str) 函数来应用它。

if __name__ == "__main__":
    app = QApplication()

    w = Widget()
    w.show()

    with open("style.qss", "r") as f:
        _style = f.read()
        app.setStyleSheet(_style)

    sys.exit(app.exec())

拥有一个通用的 qss 文件可以使您将代码的样式方面解耦,而无需将其混入一般功能中,并且可以简单地启用或禁用它。

看看这个带有更多 Widget 组件的新示例。

 1class Widget(QWidget):
 2    def __init__(self, parent=None):
 3        super(Widget, self).__init__(parent)
 4
 5        menu_widget = QListWidget()
 6        for i in range(10):
 7            item = QListWidgetItem(f"Item {i}")
 8            item.setTextAlignment(Qt.AlignCenter)
 9            menu_widget.addItem(item)
10
11        text_widget = QLabel(_placeholder)
12        button = QPushButton("Something")
13
14        content_layout = QVBoxLayout()
15        content_layout.addWidget(text_widget)
16        content_layout.addWidget(button)
17        main_widget = QWidget()
18        main_widget.setLayout(content_layout)
19
20        layout = QHBoxLayout()
21        layout.addWidget(menu_widget, 1)
22        layout.addWidget(main_widget, 4)
23        self.setLayout(layout)

这显示了一个两列的小部件,左侧有一个 QListWidget,右侧有一个 QLabel 和一个 QPushButton。运行代码时会呈现如下:

Widget with no style

如果您向先前描述的 style.qss 文件中添加内容,您可以修改先前示例的外观。

 1QListWidget {
 2    color: #FFFFFF;
 3    background-color: #33373B;
 4}
 5
 6QListWidget::item {
 7    height: 50px;
 8}
 9
10QListWidget::item:selected {
11    background-color: #2ABf9E;
12}
13
14QLabel {
15    background-color: #FFFFFF;
16    qproperty-alignment: AlignCenter;
17}
18
19QPushButton {
20    background-color: #2ABf9E;
21    padding: 20px;
22    font-size: 18px;
23}

样式主要改变了不同控件的颜色,改变了对齐方式,并包括了一些间距。您还可以在 QListWidget 的 items 上使用基于状态的样式,例如,根据它们是否被 选中 而具有不同的样式。

在应用了您在本主题中探索的所有样式选项之后,请注意,QLabel 示例现在看起来大不相同了。尝试运行代码以检查其新外观。

Widget with style

您有自由调整样式表,并为所有应用程序提供真正美观的外观。