25. 样式表

一、样式表

  为了美化窗口或控件的外观,可以通过窗口或控件的调色板给窗口或控件按照角色和分组设置颜色,还可以对窗口或控件的每个部分进行更细致的控制,这涉及窗口或控件的样式表(Qt style sheets, QSS),它是从 HTML 的层叠样式表(cascading style sheets, CSS)演化而来的。样式表由固定格式的文本构成,用窗口或控件的 setStyleSheet(styleSheet:str) 方法设置样式,其中参数 styleSheet 是样式格式符。

  定义样式表的一般规则是用 "样式属性:值" 的形式定义样式属性的值,多个样式的 "样式属性:值" 对之间用分号 ; 隔开。如果是对某一类控件进行设置,需要先说明控件的类,然后后面跟一对 {},把 "样式属性:值" 放到 {} 中。

setStyleSheet("QLabel{font:48px '华文行楷'; color:#CCCCFF; background-color:rgb(153, 204, 255)}")

  我们可以在终端中使用 pip 安装 PySide6 模块。默认是从国外的主站上下载,因此,我们可能会遇到网络不好的情况导致下载失败。我们可以在 pip 指令后通过 -i 指定国内镜像源下载

pip install pyside6 -i https://mirrors.aliyun.com/pypi/simple

  国内常用的 pip 下载源列表:

  新建一个 ui.py 文件,用来存放 UI 相关的代码。

from PySide6.QtWidgets import QWidget
from PySide6.QtWidgets import QLabel

class MyUi:
    def setup_ui(self, window:QWidget):
        window.resize(800, 600)                                                 # 1.设置窗口对象大小

        self.label = QLabel(window)                                             # 2.创建一个标签
        self.label.move(10, 10)                                                 # 3.设置标签的位置
        self.label.setText("这是一个标签")                                        # 4.设置标签的文本

        # 5.设置控件的样式
        window.setStyleSheet("QLabel{font:48px '华文行楷'; color:#CCCCFF; background-color:rgb(153, 204, 255)}")

  新建一个 widget.py 文件,用来存放业务逻辑相关的代码。

import sys

from PySide6.QtWidgets import QApplication, QWidget

from ui import MyUi

class MyWidget(QWidget):
    def __init__(self):
        super().__init__()                                                      # 1.调用父类Qwidget类的__init__()方法
      
        self.__ui = MyUi()
        self.__ui.setup_ui(self)                                                # 2.初始化页面

if __name__ == "__main__":
    app = QApplication(sys.argv)                                                # 1.创建一个QApplication类的实例
    window = MyWidget()                                                         # 2.创建一个窗口
    window.show()                                                               # 3.显示窗口
    sys.exit(app.exec())                                                        # 4.进入程序的主循环并通过exit()函数确保主循环安全结束

二、选择器

  样式表除了类名、对象名和属性名外,一般不区分大小写。样式表由 选择器(selector)和 声明(declaration)两部分构成,选择器用于选择某种类型或多个类型的控件,声明是要设置的属性和属性的值

  选择器的使用方法如下所示:

选择器 说明
* 全局选择器,选择所有控件
类名 类型选择器,匹配所有的该类以及子类的实例
类名[属性名="属性值"] 属性选择器,匹配该该属性名等于属性值的类的实例,属性可以是自定义的
#对象名称 ID 选择器,匹配指定对象名称的实例,这里的对象名称是通过 setObjectName() 方法设置的
.类名 匹配指定类的所有实例,不包含子类
父控件类名 子控件类名 后代选择器,匹配父控件中直接或间接包含的所有子控件
父控件类名 > 子控件类名 子选择器,匹配父控件中直接包含的所有子控件

  修改 ui.py 文件的内容。

from PySide6.QtWidgets import QWidget
from PySide6.QtWidgets import QLabel, QTextEdit
from PySide6.QtWidgets import QVBoxLayout

class MyUi:
    def setup_ui(self, window:QWidget):
        window.resize(800, 600)                                                 # 1.设置窗口对象大小

        layout = QVBoxLayout(window)                                            # 2.创建一个垂直布局,并设置为窗口对象的布局

        self.label1 = QLabel(window)                                            # 3.创建一个标签,并添加到垂直布局中
        layout.addWidget(self.label1)
        self.label1.setObjectName("label1")                                     # 4.设置标签的objectName
        self.label1.move(10, 10)                                                # 5.设置标签的位置
        self.label1.setText("这是一个标签")                                       # 6.设置标签的文本

        self.label2 = QLabel(window)
        layout.addWidget(self.label2)
        self.label2.setText("这是一个标签")

        self.label3 = QLabel(window)
        layout.addWidget(self.label3)
        self.label3.setText("这是一个标签")

        self.textEdit = QTextEdit(window)
        layout.addWidget(self.textEdit)

        # 7.设置控件的样式
        window.setStyleSheet(
            """
            *{
                font: 48px "华文行楷";
            }

            QLabel {
                color: #FFCCCC;
                background-color: #99CCFF;
            }

            #label1 {
                color: #FFFF99;
                background-color: #CCFF99;
            }

            QTextEdit {
                color: #66CCFF;
                background-color: pink;
            }
            """
        )

三、子控件

  一些复合型控件,例如 QSpinBox,由 QLineEdit向上的箭头向下的箭头 构成,向上的箭头和向下的箭头可以称为 子控件。对子控件的引用是在控件和子控件之间用两个连续的冒号 :: 隔开。例如:QSpinBox 控件的向上调节按钮控件和向下调节按钮控件可以分别通过 ::up-button::down-button 获取到。

子控件名 说明
groove QSlider 的凹槽
handle QScrollBarQSplitterQSlider 的手柄或滑块
corner QAbstractScrollArea 中两个滚动条之间的角落
add-line QScrollBar 增加行的按钮,即按下该按钮滚动条增加一行
sub-line QScrollBar 减少行的按钮,即按下该按钮滚动条减少一行
add-page QScrollBar 在手柄(滑块)和增加行之间的区域
sub-page QScrollBar 在手柄(滑块)和减少行之间的区域
up-arrow QHeaderView(排序指示器)、QScrollBarQSpinBox 的向上箭头
down-arrow QComboBoxQHeaderView(排序指示器)、QScrollBarQSpinBox 的向下箭头
left-arrow QScrollBar 的左箭头
right-arrow QMenuQScrollBar 的右箭头
up-button QSpinBox 的向上按钮
down-button QScrollBarQSpinBox 的向下按钮
branch QTreeView 的分支指示符
section QHeaderView 的分支指示符
text QAbstractItemView 的文本
chunk QPorgressBar 的进度块
drop-down QComboBox 的下拉按钮
indicator QAbstractItemQCheckBoxQRadioButtonQMenu(可被选中的)、QGroupBox(可被选中的)指示器
pane QTabWidget 的面板(边框)
left-cornet QTabWidget 的左角落,可用于控件 QTabWidgetr 中左角落控件的位置
right-cornet QTabWidget 的右角落,可用于控件 QTabWidgetr 中右角落控件的位置
tab QTabBarQToolBox 的选项卡
tab-bar QTabWidget 的选项卡栏,仅用于控制 QTabBarQTabWidget 中的位置
tear QTabBar 的可分离指示器
close-button QTabBar 选项卡或 QDockWidget 上的关闭按钮
float-button QDockWidget 的浮动按钮
title QDockWidgetQGroupBox 的标题
scroller QMenuQTarBar 的滚动条
separator QMenuQMainWindow 中的分隔符
tearoff QMenu 的可分离指示器
item QAbstractItemViewQMenuBarQMenuQStatusBar 中的一个项
icon QAbstractItemViewQMenu 的图标
menu-arrow 带有菜单的 QToolButton 的箭头
menu-button QToolButton 的菜单按钮
menu-indicator QPushButton 的菜单指示器

  修改 ui.py 文件的内容。

from PySide6.QtWidgets import QWidget
from PySide6.QtWidgets import QLineEdit, QComboBox, QSpinBox, QDoubleSpinBox
from PySide6.QtWidgets import QFormLayout

class MyUi:
    def setup_ui(self, window:QWidget):
        window.resize(800, 600)                                                 # 1.设置窗口对象大小
  
        layout = QFormLayout(window)                                            # 2.创建一个表单布局

        self.name_lineEdit = QLineEdit()                                        # 3.创建一个QLineEdit对象
        self.name_lineEdit.setPlaceholderText("请输入用户名")                     # 4.设置提示文本
        layout.addRow("姓名", self.name_lineEdit)                                # 5.将QLineEdit对象添加到表单布局中

        self.gender_comboBox = QComboBox()
        self.gender_comboBox.addItems(["保密", "男", "女"])
        layout.addRow("性别", self.gender_comboBox)

        self.age_spinBox = QSpinBox(minimum=0, maximum=300)
        layout.addRow("年龄", self.age_spinBox)

        self.score_doubleSpinBox = QDoubleSpinBox(minimum=0, maximum=100)
        layout.addRow("分数", self.score_doubleSpinBox)

        # 6.设置控件的样式
        window.setStyleSheet(
            """
            * {
                font: 32px "华文行楷";
            }

            QComboBox::down-arrow {
                border-image: url(assets/images/1.ico);
            }

            QSpinBox::up-arrow {
                background-color: #99CCFF;
            }

            QSpinBox::down-arrow {
                background-color: #9933FF;
            }

            QDoubleSpinBox::up-arrow {
                background-color: #FFCCCC;
            }

            QDoubleSpinBox::down-arrow {
                background-color: #CCCCFF;
            }
            """
        )

四、伪状态

  控件会根据用户的不同操作呈现出不同的状态,这些状态也被称为 “伪状态”。一个控件有多种状态,例如 活跃(active)、激活(enabled)、失效(disabled)、鼠标悬停(hover)、选中(checked)、未选中(unchecked) 和 可编辑(editable)等,根据控件所处的状态,可以给控件设置不同的外观。

  样式表的格式字符串中,控件与状态之间用冒号 : 隔开,例如 QPushButton:active{...} 设置激活时的外观;可以同时对多个状态进行设置,例如 QPushButton:active:hover{...} 设置激活或者光标悬停时的外观;可以在状态前加 !,表示相反的状态。

状态的状态 说明
active 控件处于激活状态
foucus 该项具有输入焦点
default 该项是默认值
enabled 该控件已启动
disabled 控件已失效
hover 光标悬停在该控件上
pressed 使用鼠标按下该控件
checked 该控件被选中
unchecked 该控件未被选中
on 适用于处于开启状态的控件
off 使用处于关闭关闭状态的控件
open 该控件处于打开状态
closed 该控件处于关闭状态
closable 该控件可被关闭
editable QComboBox 是可编辑的
read-only 该控件为只读
only-one 该控件是唯一的
no-frame 该控件没有边框
flat 该控件是平的
floatable 该控件是可浮动的
movable 该控件可移动
top 该控件位于顶部
buttom 该控件位于底部
left 该控件位于左侧
right 该控件处于右侧
middle 该控件位于中间
horizontal 该控件具有水平方向
vertical 该控件具有垂直方向
first 该控件是第一个
last 该控件是最后一个
indeterminate 该控件具有不确定状态
exclusive 该控件是排它项目组的一部分
non-exclusive 该控件是非排它项目组的一部分
minimized 该控件是最小的
maximized 该控件是最大化的
selected 该控件被选择
previous-selected 上一控件被选择
next-selected 下一控件被选择
window 控件是一个窗口,即顶级控件
has-children 该控件具有孩子
has-siblings 该控件具有兄弟姐妹(即同级的控件)
alternate 当 QAbstractItemView.alternatingRowColors() 被设置为 true 时,为每个交替行设置此状态,以绘制 QAbstractItemView 的行

  修改 ui.py 文件的内容。

from PySide6.QtWidgets import QWidget
from PySide6.QtWidgets import QLineEdit, QPushButton
from PySide6.QtWidgets import QGridLayout, QFormLayout

class MyUi:
    def setup_ui(self, window:QWidget):
        window.resize(800, 600)                                                 # 1.设置窗口对象大小
  
        grid_layout = QGridLayout(window)                                       # 2.创建一个栅格布局
        form_layout = QFormLayout()                                             # 3.创建一个表单布局
        grid_layout.addLayout(form_layout, 0, 0, 1, 3)                          # 4.将表单布局添加到栅格布局中

        self.name_lineEdit = QLineEdit()                                        # 5.创建单行文本编辑控件
        self.name_lineEdit.setPlaceholderText("请输入用户")                       # 6.设置单行文本编辑控件的提示文本
        form_layout.addRow("用户名", self.name_lineEdit)                         # 7.将标签和单行文本编辑控件添加到表单布局中

        self.password_lineEdit = QLineEdit()
        self.password_lineEdit.setEchoMode(QLineEdit.EchoMode.Password)
        self.password_lineEdit.setPlaceholderText("请输入密码")
        form_layout.addRow("密码", self.password_lineEdit)

        self.reset_button = QPushButton("重置")
        grid_layout.addWidget(self.reset_button, 1, 0)

        self.ok_button = QPushButton("确定")
        grid_layout.addWidget(self.ok_button, 1, 2)
  
        # 8.设置控件的样式
        window.setStyleSheet(
            """
            * {
                font: 32px "华文行楷";
            }

            QLineEdit:focus {
                background-color: #CCCCFF;
            }

            QPushButton:pressed {
                background-color: #FF6666;
            }
            """
        )

五、样式的属性

  控件有背景色、前景色及选中状态时的背景色和前景色,可以对这些颜色分别进行设置。

颜色属性名称 说明
background 设置背景的简写方法,相当于指定 background-colorbackground-imagebackground-repeatbackground-position
background-color 控件的背景色
background-image 控件的背景图像
background-repeat 如何使用背景图像填充背景区域,若未指定 background-origin 属性则在两个方向重复背景图像
background-position 背景图像在 background-origin 矩形内的位置,默认未 topleft
background-attachment 确定 QAbstractScrollArea 中的 background-image 是相对与视图滚动还是固定,默认值为 scroll
background-clip 控制绘制背景的矩形,此属性指定 background-colorbackground-image 的裁剪矩形。此属性默认值为 border(即边框矩形)
background-origin 控件背景的原点矩形,通常与 background-positionbackground-image 一起使用,默认为 padding(即边框矩形)
color 渲染文本的颜色,所有遵守 QWidget.palette 的控件都支持此属性
selection-color 所选文本或项的前景色,默认为调色板的 QPalette.HighlightedText 角色的值
selection-background-color 所选文本或项的背景色,默认为调色板的 QPalette.Highlight 角色的值

  修改 ui.py 文件的内容。

from PySide6.QtWidgets import QWidget
from PySide6.QtWidgets import QTextEdit
from PySide6.QtWidgets import QVBoxLayout

class MyUi:
    def setup_ui(self, window:QWidget):
        window.resize(800, 600)                                                 # 1.设置窗口对象大小
  
        layout = QVBoxLayout(window)                                            # 2.创建一个垂直布局

        self.textEdit = QTextEdit()                                             # 3.创建一个多行文本编辑控件
        layout.addWidget(self.textEdit)                                         # 4.将多行文本编辑控件添加到布局中

        self.textEdit.setText("这是多行文本编辑控件")                              # 5.设置多行文本编辑控件的文本
  
        # 6.设置控件的样式
        window.setStyleSheet(
            """
            QTextEdit {
                font: 32px "华文行楷";
                color: #99CCFF;
                background-image: url(assets/images/1.jpg);
                selection-color: #FF99CC;
                selection-background-color: #FFFF66;
            }
            """
        )

六、盒子模型

  大多数控件都是长方形的,一个长方形控件由 ContentPaddingBorderMargin 4 部分构成,每个部分都是矩形。Content 矩形是 除掉边距、边框和填充之后的部分,默认情况下,边距、边框和填充的距离都为 0,因此这 4 个矩形是重合的。可以用样式表分别设置这四个矩形之间的距离、边框的颜色。

盒子模型

  Content输入内容的区域,可以设置 Content 区域宽度和高度的最大值和最小值,属性名称分别为 max-widthmax-heightmin-widthmin-height

  对于 Padding 区域,用 padding 属性可以分别 设置 PaddingContent 在上、右、下和左方向的距离,也可用 padding-toppadding-rightpadding-bottompadding-left 属性分别设置距离。

  Border 区域可以设置的属性比较多,如下所示。

属性名称 说明
border 设置边框的简写方法,相当于指定 border-colorborder-styleborder-width
border-top 设置控件顶部边框的简写方法,相当于指定 border-top-colorborder-top-styleborder-top-width
border-right 设置控件右边框的简写方法,相当于指定 border-right-colorborder-right-styleborder-right-width
border-bottom 设置控件底部边框的简写方法,相当于指定 border-bottom-colorborder-bottom-styleborder-bottom-width
border-left 设置控件左边框的简写方法,相当于指定 border-left-colorborder-left-styleborder-left-width
border-color 边框边界的颜色,相当于指定 border-top-colorborder-right-colorborder-bottom-colorborder-left-color,默认值为控件的前景色
border-top-color 边框顶部边界线的颜色
border-right-color 边框右边界线的颜色
border-bottom-color 边框底部边界线的颜色
border-left-color 边框左边界线的颜色
border-radius 边框角落的圆角半径,相当于指定 border-top-left-radiusborder-top-right-radiusborder-bottom-right-radiusbordedr-bottom-left-radius,默认值为 0
border-top-left-radius 边框左上角圆角的半径
border-top-right-radius 边框右上角圆角的半径
border-bottom-right-radius 边框右下角圆角的半径
bordedr-bottom-left-radius 边框左下角圆角的半径
border-style 边框边界线的样式(实线 solid、虚线 dashed、点划线 dotted等),默认为 None
border-top-style 边框顶部边界线的样式
border-right-style 边框右侧边界线的样式
border-bottom-style 边框底部边界线的样式
border-left-style 边框左侧边界线的样式
border-width 边框的宽度,相当于指定 border-top-widthborder-right-widthborder-bottom-widthborder-left-width
border-top-width 边框顶部边界线的宽度
border-right-width 边框右侧边界线的宽度
border-bottom-width 边框底部边界线的宽度
border-left-width 边框左侧边界线的宽度
border-image 填充边框的图像,该图像被分割成 9 个部分,并在必要时适当的拉伸

  对于 Margin 区域可以 设置页边距margin 属性 设置控件的边距,等效于指定 margin-topmargin-rightmargin-bottommargin-left,默认为 0,margin-topmargin-rightmargin-bottommargin-left 分别 设置控件的上、右、下和左侧的边距

  修改 ui.py 文件的内容。

from PySide6.QtWidgets import QWidget
from PySide6.QtWidgets import QLabel

class MyUi:
    def setup_ui(self, window:QWidget):
        window.resize(800, 600)                                                 # 1.设置窗口对象大小

        self.label = QLabel(window)                                             # 2.创建一个标签控件
        self.label.setText("这是一个标签控件")                                     # 3.设置标签控件的文本
  
        # 4.设置控件的样式
        window.setStyleSheet(
            """
            QLabel {
                font: 32px "华文行楷";

                color: #99CCFF;
                background-color: #FFFF66;

                min-width: 300px;
                min-height: 100px;

                max-width: 300px;
                max-height: 100px;

                padding: 10px;

                border-style: dashed;
                border-color: #FFCC99;
                border-width: 5px;
                border-radius: 5px;

                margin: 10px;
            }
            """
        )
posted @ 2025-01-13 21:05  星光映梦  阅读(145)  评论(0)    收藏  举报