16-2_Qt 5.9 C++开发指南_使用样式表Qss自定义界面

进行本篇介绍学习前,请先参考链接01_1_Qt工程实践_Qt样式表Qss,后再结合本篇进行融合学习如何使用样式表定义界面。

文章目录

  • 1. Qt样式表
  • 2. Qt样式表句法
    • 2.1 一般句法格式
    • 2.2 选择器 (selector)
    • 2.3 子控件(sub-controls)
    • 2.4 伪状态(pseudo-states)
    • 2.5 属性
  • 3. 样式表的使用
    • 3.1 程序中使用样式表
    • 3.2 样式定义的明确性
    • 3.3 样式定义的级联性

1. Qt样式表

Qt 样式表 (style sheet)是用于定制用户界面的强有力的机制,其概念、术语是受到HTML 中的级联样式表(Cascading Style Sheets,CSS)启发而来的,只是 Qt 样式表是应用于窗体界面的。

与 HTML 的 CSS 类似,Qt的样式表是纯文本的格式定义,在应用程序运行时可以载入和解析这些样式定义。使用样式表可以定义各种界面组件(QWidget 类及其子类)的样式,从而使应用程序的界面呈现不同的效果。很多软件具有换肤功能,使用 Qt 的样式表就可以容易地实现这样的功能。
在 UI设计器中集成了 Qt 样式表的编辑功能。在设计窗时,选择窗体或某个界面组件,单击鼠标右键,在弹出的快捷菜单中选择“Change styleSheet”菜单项就可以出现样式表编辑对话框。

2. Qt样式表句法

2.1 一般句法格式

Qt样式表的句法 (syntax)与HTML的CSS 法几乎完全同。Qt 样式表包含一系列的样式法则,一个样式法则由一个选择器(selector)和一些声明(declaration)组成。例如:

QPlainTextEdit{font: 12pt“仿宋";color: rgb(2552550);background-color: rgb(000)
}

其中,QPlainTextEdit就是选择器,表明后面花括号里的样式声明应用于QPlainTextEdit类及其子类。样式声明部分是样式法则列表,每个样式法则由属性和值(key-value)组成,每条法则用分号结束。每条样式法则由“属性:值”构成,例如:

font: 12pt“仿宋";

表示 font 属性,字体大小为 12pt,字体名称为“仿宋”;当一个属性有多个值时,多个值用空格隔开。

2.2 选择器 (selector)

Qt样式表支持 CSS2 中定义的所有选择器,表 16-1显示的是一些常用的选择器。
在这里插入图片描述
这些选择器的定义为选择界面组件提供了灵活性。选择器可以组合使用,一个样式声明可以应用于多个选择器,例如:

QPlainTextEdit,QLineEdit,QPushButton,QCheckBox{color: rgb(2552550);background-color: rgb(000);
}

这个样式声明将同时应用于 QPlainTextEdit、QLineEdit、QPushButton和QCheckBox 的实例。

QLineEdit[readOnly-"true"], QCheckBox[checked-"true"]
{ background-color: rgb(255,0,0) }

上面的这个样式应用于readOnly 属性为true 的QLineEdit和checked 属性为true的QCheckBox实例,功能是使其背景颜色为红色。
在Qt中,可以为一个界面组件使用QObject::setProperty()设置一个动态属性,例如,在数据表编辑界面上,一些字段是必填字段,就可以为这些字段的关联组件设置一个required 属性为 true,如:

editName-> setProperty("required""true");
comboSex-> setProperty("required”,"true");
checkAgree-> setProperty("reauired","true");

这样设置了三个界面组件的动态属性 required 为 true。

那么,可以应用下面的样式将这种必填字段的背景颜色设置为亮绿色

*[required="true"] {background-color: lime)

2.3 子控件(sub-controls)

对于一些组合的界面组件,需要对其子控件进行选择,如 QComboBox 的下拉按钮,或QSpinBox 的上、下按钮。通过选择器的子控件可以对这些界面元素进行显示效果控制。例如:

QComboBox::drop-down{ image: url(:/images/images/down.bmp);}

选择器QComboBox:drop-down 选择了 QCombBox 的drop-down 子控件,定义的样式是设置其image 属性为资源文件中的图片 down.bmp。

QSpinBox::up-button{ image: url(:/images/images/up.bmp);}
QSpinBox::down-button{ image: url(:/images/images/down.bmp);

这两条样式定义语句分别定义了 QSpinBox 的上、下按钮的图片,用资源文件中的图片替代了缺省的图片。

Qt 中常用的子控件见表 16-2,所有子控件的详细描述见 Qt 的帮助文档
在这里插入图片描述
在这里插入图片描述

2.4 伪状态(pseudo-states)

选择器可以包含伪状态,使得样式法则只能应用于界面组件的某个状态,也就是一种条件应用法则。伪状态出现在选择器的后面,用一个分号 ":"隔开。如下面的样式法则:

QLineEdit:hover{background-color: black;color: yellow;
}

定义了当鼠标移动到 QLineEdit 上方时 (hover),改变 QLineEdit 的背景色和前景色。

可以对伪状态取反,方法是在伪状态前面加一个感叹号 (!),如:

QLineEdit:!read-only{ background-color: rgb(235,255,251);}

这定义了 readonly 属性为 false 的QLineEdit 的背景色。

伪状态可以串联使用,相当于逻辑与的计算,例如:

QCheckBox:hover:checked{ color: red; }

这定义了当鼠标移动到一个被勾选了的 QCheckBox 组件上方时,其字体颜色变为红色。

伪状态可以并联使用,相当于逻辑或的计算,例如:

QCheckBox:hover,QCheckBox:checked{ color: red; }

这表示鼠标移动到QCheckBox 组件上方,或QCheckBox 组件被勾选时,字体颜色变为红色。

子控件也可以使用伪状态,如:

QCheckBox::indicator:checked{ image: url(:/images/images/checked.bmp);}
QCheckBox::indicator:unchecked{image: url(:/images/images/unchecked.bmp);}

这里定义了 QCheckBox 的 indicator 在 checked 和unchecked 两种状态下的显示图片。

Qt 样式定义中常见的一些伪状态见表 16-3,熟悉这些伪状态并灵活应用可以定义自己想要的界面效果。

在这里插入图片描述
在这里插入图片描述

2.5 属性

Qt样式表内对每一个选择器可定义多条样式规则,每个规则是一个“属性:值”对,Qt 样式表中可定义的属性很多,可以在Qt 的帮助文件中查找“Qt Style Sheets Reference”查看所有属性的详细说明。

使用样式表可以定义组件复杂的显示效果。每个界面组件都可以用如图 16-7 所示的盒子模型(BoxModel)来表示,模型由四个同心矩形表示。
在这里插入图片描述

(1) content 是显示内容矩形区域,如 QLineEdit 用于显示文字的区域,min-width、max-width、min-height 和 max-height 属性定义最大/最小宽度或高度,就是定义这个矩形区,例如:

QLineEdit{
min-width:50px;
max-height:40px;}

这定义QLineEdit 最小宽度为 50px,最大高度是 40px,其中 px 是单位,表示像素。

(2) padding 是包围 content 的矩形区域,通过 padding 属性可以定义 padding 的宽度,或padding-top、padding-bottom、padding-left 和 padding-right 分别定义 padding 的上、下、左、右宽度,例如:

QLineEdit{ padding: 0px 10px 0px 10px;}

这设定 padding 的上、右、下、左的宽度,它等效于

QLineEdit{
padding-top:0px;
padding-right:10px;
padding-bottom: 0px;
padding-left:10px;
}

(3) border 是包围 padding 的边框,通过 border 属性 (或 border-width、border-style、border-color)可以定义边框的线宽、线型和颜色,也可以分别定义 border 的上、下、左、右的线宽和颜色。使用border-radius 可以定义边框转角的圆弧半径,从而构造具有圆角矩形的编辑或按钮等组件,例如:

QLineEdit{
border-width: 2px;
border-style: solid;
border-color: gray;
border-radius: 10px;
padding: 0px 10px;
}

这使得 QLineEdit 具有灰色边框线条、圆角矩形的效果。

通过 border-radius、min-width 和 min-height 等属性可以设计圆形的按钮,如:

QPushButton {border: 2px groove red;border-radius: 30px;min-width:60px;min-height:60px;
}

使得边框转角半径等于 content 宽度或长度的一半,宽度和长度相等,就可以得到一个圆形的按钮。
使用 border-image 属性还可以为组件设置背景图片,图片会填充 border 矩形框之内的区域,一般使用材质图片设置背景,以使界面具有统一的特色,例如:

QLineEdit,QPushButton{border-image: url(:/images/images/border.jpg);}

(4) margin 是 border 之外与父组件之间的空白边距,可以分别定义上、下、左、右的边距大小。

缺省的情况下,margin、border-width 和 padding 属性缺省值为零,这种情况下,四个同心矩形就是重合的一个矩形。
使用Qt 样式表可以为界面组件设计各种美观的显示效果,美观而特殊的界面不仅需要编程的能力,更重要的是美工设计能力。

3. 样式表的使用

3.1 程序中使用样式表

有多种方法可以应用样式表。
第一种是在使用Qt Designer 设计窗体时,直接用样式表编辑器为窗体或窗体上的某个部件设计样式表,则设计的样式保存在窗体的 ui 文件里,窗体创建时会自动应用所设计的样式表。这样设计的样式表对应用程序是固定的,无法取得换肤的效果,而且需要为每个窗体都设计样式表,重复性工作量太大。
第二种是使用 setStyleSheet 函数应用样式,使用qApp 的 setStyleSheet()函数可以为应用程序全局设置样式,使用QWidget::setStyleSheet()可以为一个窗口、一个对话框或一个界面组件设置样式。例如:

qApp->setStyleSheet("QLineEdit { background-color: gray }");

这里使用应用程序全局变量 qApp 为 QLineEdit 设置样式,如果应用程序内的某些 QLineEdit组件没有再被设置样式,则 QLineEdit 组件的背景色为灰色。

MainWindow->setStyleSheet{ "QLineEdit { background-color: lime }");

这是为主窗口MainWindow 内的QLineEdit 组件设置样式,即背景色为亮绿色

editName->setstyleSheet("color: blue;""background-color: yellow;""selection-color: yellow;""selection-background-color: blue;");

这是设置一个 ObjectName 为 editName 的 QLineEdit 组件的样式,注意这时在样式表中无需设置selector 名称,所设置的样式是应用于editName 这个 QLineEdit 组件的。

**这样将样式表固定在程序中,很显然也是无法实现切换界面效果的。为了实现切换界面效果(换肤)的目的,一般将样式定义表保存为 qss 后缀的纯文本文件,然后在程序中打开文件,读取文本内容,再调用 setStyleSheet()函数应用样式。**示例代码如下:

QFile file(":/qss/mystyle.qss”);
file.open(QFile::ReadOnly);
QString styleSheet = QString::fromLatinl(filereadAll());
qApp->setstyleSheet (styleSheet);

3.2 样式定义的明确性

当多条样式法则对一个属性定义了不同值时,就会出现冲突,例如:

QPushButton#btnSave { color: gray }
QPushButton { color: red }

这两条法则都可以应用于ObiectName 为 btnSave 的QPushButton 组件,都定义了其前景色,这就会出现冲突。这时,选择器的明确性 (specificity) 决定组件适用的样式法则,即法则应用于更明确的组件。

在上面的例子中QPushButton#btSave 被认为是比QPushButton 更明确的选择器因为它指向一个对象,而不是 QPushButton 的所有实例。所以,如果是在一个窗口上应用以上两条法则,则 btnSave 按钮的前景色为 gray,而其他按钮的前景色为red。

同样,具有伪状态的选择器被认为比没有伪状态的选择器明确性更强,如:

QPushButton:hover { color: white }
QPushButton { color: red }

这样,当鼠标在按钮上停留时颜色为 white,否则颜色为 red。
如果两个选择器具有相同的明确性,则以法则出现的先后顺序为准,后出现的法则起作用,例如:

QPushButton:hover { color: white }
QPushButton:enabled { color: red }

这里的两个选择器具有相同的明确性,所以,当鼠标停留在一个使能的按钮上时,只有第二条法则起作用。这种情况下,如果希望不出现冲突,应该修改法则以使其更明确,如下面这两条法则是不冲突的。

QPushButton:hover:enabled { color: white }
QPushButton:enabled { color: red }

父子关系的两个类作为选择器时,具有相同的明确性,例如:

QPushButton { color: red }
QAbstractButton { color: gray }

这两个选择器的明确性相同,所以只依赖于语句的先后顺序
确定法则的明确性,Qt 样式表遵循 CSS2 的规定,在设计样式表时应尽量明确并避免冲突情况。

3.3 样式定义的级联性

样式定义可以在 qApp、窗口或一个具体组件中定义,任何一个组件的样式是其父组件、父窗口和qApp 的样式的融合。当出现冲突时,组件会使用离自己最近的样式定义,即按顺序使用组件自己的样式、或父组件的样式定义、或父窗口的样式定义,或qApp 的样式定义,而不考虑样式选择器的确定性。

例如,在QApplication 中设置全局样式:
qApp->setStyleSheet("QPushButton { color: red }");

那么应用程序中所有未再定义样式的QPushButton 的前景颜色为red。

如果在MainWindow 中再定义样式:
MainWindow->setStyleSheet("QPushButton { color: blue }");
则MainWindow 上的按钮的前景色为 blue,而不是 red。

如果MainWindow上有一个名称为 btnSave的QPushButton 按钮,其定义样式如下:

btnSave->setStyleSheet("color: yellow; background-color: black;");
则按钮 btnSave 按照自己的样式显示前景和背景色。

Qt 样式表功能强大,可以设计自己想要的界面效果,但是这需要有较好的美工设计基础,需要在使用样式表的过程中不断尝试和总结经验。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/28435.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

构建Docker容器监控系统(cadvisor+influxDB+grafana)

目录 一、部署 1、安装docker-cd 2、阿里云镜像加速 3、下载组件镜像 4、创建自定义网络 5、创建influxdb容器 6、创建Cadvisor 容器 7、创建granafa容器 一、部署 1、安装docker-cd [rootlocalhost ~]# iptables -F [rootlocalhost ~]# setenforce 0 setenforce: SELi…

RS485实验

RS485实验 介绍 RS485采用差分信号进行传输,半双工通信。RS485是一个总线,在同一总线上最多可以挂接32个节点。通信流程简单理解为默认为接收状态,发送数据时切换为发送状态,数据发送完毕后切换为接收状态。发送和接收分别由一个…

[考研机试] KY20 完数VS盈数 清华大学复试上机题 C++实现

描述 一个数如果恰好等于它的各因子(该数本身除外)子和,如:6321。则称其为“完数”;若因子之和大于该数,则称其为“盈数”。 求出2到60之间所有“完数”和“盈数”。 输入描述: 题目没有任何输入。 输出描述&#…

87 | Python人工智能篇 —— 机器学习算法 决策树

本教程将深入探讨决策树的基本原理,包括特征选择方法、树的构建过程以及剪枝技术,旨在帮助读者全面理解决策树算法的工作机制。同时,我们将使用 Python 和 scikit-learn 库演示如何轻松地实现和应用决策树,以及如何对结果进行可视化。无论您是初学者还是有一定机器学习经验…

MachineLearningWu_13/P60-P64_Tensorflow

P60-P64的学习目录如下, x.1 TF网络模型实现 以一个简单的TF的分类网络为例,将模型翻译成框架下的语义,即如右侧所表达的。 当然上面对于分类网络的解释是一个简洁的解释,我们来进行更加具象的了解一下。左边是机器学习的三步骤&…

iTextSharp 生成PDF

示例代码定义了一个名为PdfController的API控制器,其中的GeneratePdf方法创建了一个新的PDF文档,并将内容添加到文档中。最后,将文档内容转换为字节数组,并通过File方法返回给前端。 注意,你需要在你的项目中添加对iT…

LeetCode题解:判断是否能拆分数组

⭐简单说两句⭐ 作者:后端小知识 CSDN个人主页:后端小知识 🔎GZH:后端小知识 🎉欢迎关注🔎点赞👍收藏⭐️留言📝 上周做了力扣周赛的题,给大家分享一个中等题目&#xff…

文章采集伪原创发布工具-147采集

在当今信息爆炸的时代,企业和个人都意识到了获取高质量、原创的内容的重要性。然而,手动撰写大量的原创内容是一项耗时费力的任务。为了解决这个问题,我向您介绍一款颠覆性的数据采集工具——147采集。 147采集是一款专业且高效的数据采集软件…

Linux安装配置nginx+php搭建以及在docker中配置

Linux安装配置nginxphp搭建以及在docker中配置 文章目录 Linux安装配置nginxphp搭建以及在docker中配置1.nginx源码包编译环境和安装相应的依赖1.1 安装编译环境1.2 安装pcre库、zlib库和openssl库 2.安装nginx2.1 在[nginx官网](https://nginx.org/en/download.html)上获取源码…

IDEA 指定spring.profiles.active本地启动

spring.profiles.activedev spring.profiles.activepro

Android开发实践:Android.mk模板

关于Android NDK开发的文章已经比较多了,我的博客中也分享了很多NDK开发相关经验和技巧,今天简单写了一个 Android.mk 的示例模板,供初学者参考。 本模板主要给大家示例 Android NDK 开发中的如下几个问题: 如何自动添加需要编译…

vb+SQL车辆管理系统设计与实现

摘 要 随着信息时代的到来,信息高速公路的兴起,全球信息化进入了一个新的发展时期。人们越来越认识到计算机强大的信息模块处理功能,使之成为信息产业的基础和支柱。 我国经济的快速发展,汽车已经成为人们不可缺少的交通工具。对于拥有大量车辆的机关企事业来说,车辆的…

15_基于Flink将pulsar数据写入到ClickHouse

3.8.基于Flink将数据写入到ClickHouse 编写Flink完成数据写入到ClickHouse操作, 后续基于CK完成指标统计操作 3.8.1.ClickHouse基本介绍 ClickHouse 是俄罗斯的Yandex于2016年开源的列式存储数据库(DBMS),使用C语言编写,主要用…

K最近邻算法:简单高效的分类和回归方法(三)

文章目录 🍀引言🍀训练集和测试集🍀sklearn中封装好的train_test_split🍀超参数 🍀引言 本节以KNN算法为主,简单介绍一下训练集和测试集、超参数 🍀训练集和测试集 训练集和测试集是机器学习和深…

【LeetCode】数据结构题解(11)[用队列实现栈]

用队列实现栈 😉 1.题目来源👀2.题目描述🤔3.解题思路🥳4.代码展示 所属专栏:玩转数据结构题型❤️ 🚀 >博主首页:初阳785❤️ 🚀 >代码托管:chuyang785❤️ &…

C语言文件操作基本方法

1、文件的分类 ANSI C 的缓冲文件系统 缓冲文件系统 缓冲文件系统是指,系统自动地在内存区为每个正在使用的文件开辟一个缓冲区。 从内存向磁盘输出数据时,必须首先输出到缓冲区中。待缓冲区装满后,再一起输出到磁盘文件中。 从磁盘文件向内…

云原生周刊:KubeCon China 2023 详细议程公布 | 2023.8.7

开源项目推荐 Spiderpool Spiderpool 是一个 Kubernetes 底层网络解决方案。它提供丰富的 IPAM 功能和 CNI 集成能力,为开源社区的 CNI 项目提供支持,允许多个 CNI 有效协作。它能让底层 CNI 在裸机、虚拟机和任何公共云等环境中完美运行。 Preevy P…

Python爬虫的Selenium(学习于b站尚硅谷)

目录 一、Selenium  1.为什么要学习Selenium  (1)什么是Selenium  (2)为什么使用selenium?  (3)代码演示 2. selenium的基本使用  (1)如何安装selenium  (2…

探析STM32标准库与HAL库之间的差异与优劣

引言: 在嵌入式开发领域,STMicroelectronics的STM32系列芯片广受欢迎。STM32提供了两种主要的软件库,即标准库和HAL库,用于开发各种应用。本文将探讨这两种库之间的差异,比较它们的优劣,并分析在选择库时需…

数仓架构模型设计参考

1、数据技术架构 1.1、技术架构 1.2、数据分层 将数据仓库分为三层,自下而上为:数据引入层(ODS,Operation Data Store)、数据公共层(CDM,Common Data Model)和数据应用层&#xff…