Qt 实战(11)样式表 | 11.1、样式表

文章目录

前言:

在开发图形用户界面(GUI)应用时,美观和一致性是吸引用户的重要因素。Qt,作为一个功能强大的跨平台C++图形用户界面应用程序开发框架,提供了一个强大的工具------Qt样式表(Qt Style Sheets, QSS),来帮助开发者轻松地定制和美化应用程序的界面。

一、样式表:为GUI应用赋予视觉美感

1、简介

Qt样式表是一种类似于层叠样式表(Cascading Style Sheets, CSS)的声明性语言,它允许开发者通过简单的规则来定义Qt控件的外观和布局。这些规则可以应用于单个控件,也可以应用于整个应用程序的所有控件,从而实现一致且吸引人的用户界面。

2、样式表语法

2.1、样式规则

样式表包含了一系列的样式规则,每个样式规则由选择器声明组成。选择器指定了受该规则影响的部件,声明指定了这个部件上要设置的属性。例如:

cpp 复制代码
StyleSheetExample::StyleSheetExample(QWidget *parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);

    ui.m_pOkBtn->setStyleSheet("QPushButton{color:red}");
}

Qt样式表中声明(即:规则中的key与value)一般不区分大小写,例如:QPushButton{Color:Red}QPushButton{color:red}效果是一样的,但是,选择器是区分大小写的。同时多个选择器可以指定相同的规则使用;隔开,例如:

cpp 复制代码
QPushButton, QLineEdit, QComboBox{color:red}

样式规则的声明部分是一些"属性":"值"对组成的列表,它们包含在{}中,使用;隔开,例如:

cpp 复制代码
QPushButton(color:red; background-color:white)

在Qt帮助文档中,使用Qt Style Sheets Reference关键字对应文档中的List of Properties 一项中查看Qt样式表支持的所有属性。

2.2、选择器类型

类型 示例 功能
通用选择器 * 匹配所有部件
类型选择器 QPushButton 匹配所有QPushButton实例和它的所有子类
属性选择器 QPushButton[flag="false"] 匹配QPushButton的属性flag为false的实例
类选择器 .QPushButton 匹配所有QPushButton实例,但不包含它的子类
ID选择器 QPushButton#okButton 匹配所有QPushButton中以okButton为对象名的实例
后代选择器 QDialog QPushButton 匹配所有QPushButton实例,它们必须是QDialog的子孙部件
孩子选择器 QDialog>QPushButton 匹配所有的QPushButton实例,它们必须是QDialog的直接子部件

2.3、伪状态

样式表中的伪状态(pseudo-states)是一种强大的功能,它允许开发者根据小部件(widget)的特定状态来应用不同的样式规则。这些状态描述了小部件在特定情况下的外观,比如鼠标悬停、选中、禁用等。伪状态出现在选择器的末尾,通过冒号:进行标记。例如:

cpp 复制代码
/* 定义 QPushButton 的 :hover 伪状态样式 */
ui.m_pOkBtn->setStyleSheet("QPushButton:hover{background-color:darkblue;}");

伪状态与普通样式混合使用,如下:

cpp 复制代码
/* 定义 QPushButton 的样式 */
ui.m_pOkBtn->setStyleSheet("QPushButton{background-color:red;} \
    QPushButton:hover{background-color:darkblue;} \
    QPushButton:pressed{background-color:yellow;}");

Qt Style Sheets Reference关键字对应帮助文档的List of Pseudo-States一项中列出了Qt支持的所有伪状态。

2.4、设置子控件状态

对于一些复杂的部件修改样式,可能需要访问它们的子控件,例如:QComboBox的下拉按钮、还有QSpinBox的向上和向下箭头等。选择器可以包含子控件来对部件的特定子控件应用规则,例如:

cpp 复制代码
QComboxBox::drop-down{image:url(dropdown.png)}

这样的规则可以改变所有QComboBox部件的下拉按钮的样式。Qt Style Sheets Reference关键字对应帮助文档的List of Stylable Widgets一项中列出了所有可以使用的样式表来自定义样式的Qt部件,List of SubControls一项中列出了所有可用的子控件。

3、样式表继承与优先级

Qt样式表的继承与优先级是确保界面元素正确显示的关键机制,通过理解选择器的权重和层叠性,可以有效控制样式的应用。以下是对其具体介绍:

3.1、样式表继承

  • 基本概念: 在Qt中,样式表的继承指的是子控件自动获取父控件的某些样式属性。例如,如果一个QWidget设置了背景颜色,那么它的所有子控件也会默认继承这个背景颜色,除非子控件显式地覆盖了这一属性。
  • 实现方式: 要实现样式继承,通常不需要额外的操作。只需为父控件设置样式,子控件就会自动继承这些样式。如果需要阻止某些样式属性的继承,可以在子控件中明确设置该属性。

3.2、样式表优先级

Qt样式表的优先级规则是由选择器的具体性、样式表加载的顺序以及内联样式等因素共同决定的。以下是对Qt样式表优先级规则的具体介绍:

  • 选择器具体性:

    • 更具体的元素选择器: 在QSS中,更具体的元素选择器(如#id, .class)比通用选择器(如或E>)具有更高的优先级。例如,QPushButton { color: red; }中的QPushButton是一个类型选择器,而.QPushButton则是一个类选择器,它们的优先级高于通用选择器如* { color: green; }
    • 伪状态选择器: 带有伪状态的选择器(如:hover)比不带伪状态的选择器具有更高的优先级。例如,QPushButton:hover { background-color: yellow; }中的:hover伪状态选择器会在鼠标悬停时覆盖普通状态下的样式设置。
  • 样式表加载顺序:

    • 内联样式: 直接在控件的setStyleSheet()方法中设置的样式表具有最高的优先级,因为它们是在运行时立即生效的。例如,button->setStyleSheet("QPushButton { background-color: yellow; }");中的样式设置会覆盖其他所有样式表中的相同设置。
    • 外部文件加载: 在resources目录下的*.qss文件中定义的样式,其优先级高于其他外部样式表。例如,如果应用程序启动时应用了styles.qss文件中的样式,这些样式将优先于HTML或XML文档中的样式。
  • 默认主题中的样式:

    • 如果应用使用了Qt的主题(如FusionCupertino等),默认主题中的样式具有较高的优先级,可以在主题文件中覆盖。例如,Fusion主题中的样式设置会优先于应用程序中自定义的样式表,除非在主题文件中进行了覆盖。
  • 选择器的权重:

    • ID选择器: ID选择器(如#objectName)具有最高的优先级,因为它是唯一匹配特定对象的选择器。例如,#myButton { font-size: 18pt; }中的#myButton会选择objectNamemyButton的对象并应用样式。
    • 类选择器: 类选择器(如.className)的优先级次于ID选择器,但高于元素选择器。例如,.redButton { color: red; }中的.redButton会选择所有class属性为redButton的对象并应用样式。
    • 元素选择器: 元素选择器(如E*>)的优先级最低,因为它是最不具体的选择器。例如,QWidget > QPushButton { border: 2px solid black; }中的QWidget > QPushButton会选择所有QWidget的直接子控件QPushButton并应用样式。

3.3、解决冲突

在Qt样式表中,当多个选择器对同一个控件的相同属性设置了不同的值时,就会产生冲突。为了解决这些冲突,Qt样式表遵循以下原则:

  • 更具体的选择器优先

    • 如果一个选择器比另一个选择器更具体(例如,一个选择器指定了ID,而另一个选择器只指定了类型),则更具体的选择器设置的样式将优先生效。
    • 例如,对于QPushButton,明确指定了ID的QPushButton#okButton将覆盖普通QPushButton的颜色设定。
  • 附加状态的选择器优先

    • 带有伪状态(如:hover:checked等)的选择器比没有伪状态的选择器更特殊。
    • 例如,QPushButton:hover{color:white}会比QPushButton{color:red}更优先,当鼠标悬浮在按钮上时,字体颜色会显示为白色。
  • 相同特殊性下的后设置原则

    • 如果两个选择器的特殊性一致,则后设置的样式将覆盖先设置的样式。
    • 例如,QPushButton:enabled{color:red}QPushButton:hover{color:white}具有相同的特殊性,但当鼠标悬浮在一个可用的按钮上时,按钮文字的颜色为红色,因为QPushButton:enabled是后设置的。然而,如果调整顺序或增加选择器的特殊性(如QPushButton:hover:enabled{color:white}),则可以改变这一结果。

3.4、样式表层叠

样式表层叠指的是可以在多个层级上设置部件的样式,并根据优先级和特异性来决定最终应用的样式。

  • 样式表的来源:
    • 应用程序级别: 通过 QApplication::setStyleSheet() 设置的样式表。
    • 窗口级别 :通过 QWidget::setStyleSheet() 设置的样式表。
    • 控件级别 :通过特定控件的 setStyleSheet() 方法设置的样式表。
  • 优先级:
    • 控件级别:特定控件上的样式表优先级最高。
    • 窗口级别:在窗口或对话框上设置的样式表。
    • 应用程序级别 :在 QApplication 上设置的样式表优先级最低。
  • 特异性:
    • ID 选择器 (例如 #myWidget):特异性最高。
    • 类选择器 (例如 .myClass)和伪类选择器(例如 :hover)。
    • 元素选择器 (例如 QPushButton)和伪元素选择器(例如 ::before)。
  • 重要性:
    • 使用!important标记可以强制某个属性覆盖其他规则。然而,在Qt样式表中过度使用!important可能会导致样式表难以维护和管理。

4、总结

Qt 样式表是一个功能强大且易于使用的工具,它允许开发者以类似CSS的方式自定义Qt控件的外观。通过理解Qt 样式表的基本概念、优势、基本用法和层叠规则,开发者可以创建出美观、易用且跨平台的Qt应用程序。

相关推荐
尘浮生1 分钟前
Java项目实战II基于微信小程序的电影院买票选座系统(开发文档+数据库+源码)
java·开发语言·数据库·微信小程序·小程序·maven·intellij-idea
hopetomorrow15 分钟前
学习路之PHP--使用GROUP BY 发生错误 SELECT list is not in GROUP BY clause .......... 解决
开发语言·学习·php
小牛itbull25 分钟前
ReactPress vs VuePress vs WordPress
开发语言·javascript·reactpress
请叫我欧皇i34 分钟前
html本地离线引入vant和vue2(详细步骤)
开发语言·前端·javascript
闲暇部落36 分钟前
‌Kotlin中的?.和!!主要区别
android·开发语言·kotlin
GIS瞧葩菜1 小时前
局部修改3dtiles子模型的位置。
开发语言·javascript·ecmascript
chnming19871 小时前
STL关联式容器之set
开发语言·c++
熬夜学编程的小王1 小时前
【C++篇】深度解析 C++ List 容器:底层设计与实现揭秘
开发语言·数据结构·c++·stl·list
GIS 数据栈1 小时前
每日一书 《基于ArcGIS的Python编程秘笈》
开发语言·python·arcgis
Mr.131 小时前
什么是 C++ 中的初始化列表?它的作用是什么?初始化列表和在构造函数体内赋值有什么区别?
开发语言·c++