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(255,255,0);background-color: rgb(0,0,0)
}
其中,QPlainTextEdit就是选择器,表明后面花括号里的样式声明应用于QPlainTextEdit类及其子类。样式声明部分是样式法则列表,每个样式法则由属性和值(key-value)
组成,每条法则用分号结束。每条样式法则由“属性:值”
构成,例如:
font: 12pt“仿宋";
表示 font 属性,字体大小为 12pt,字体名称为“仿宋”;当一个属性有多个值时,多个值用空格隔开。
2.2 选择器 (selector)
Qt样式表支持 CSS2 中定义的所有选择器,表 16-1显示的是一些常用的选择器。
这些选择器的定义为选择界面组件提供了灵活性。选择器可以组合使用,一个样式声明可以应用于多个选择器,例如:
QPlainTextEdit,QLineEdit,QPushButton,QCheckBox{color: rgb(255,255,0);background-color: rgb(0,0,0);
}
这个样式声明将同时应用于 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 样式表功能强大,可以设计自己想要的界面效果,但是这需要有较好的美工设计基础,需要在使用样式表的过程中不断尝试和总结经验。
相关文章:

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 伪状…...
chatgpt openai API报错openai.error.APIConnectionError
openai.error.APIConnectionError: Error communicating with OpenAI: 报错信息无用方案问题查看urllib3版本方法 可行方案法1法2:自己找包安装 报错信息 raise error.APIConnectionError( openai.error.APIConnectionError: Error communicating with OpenAI: HTT…...

【果树农药喷洒机器人】Part1:研究现状分析以及技术路线介绍
本专栏介绍:付费专栏,持续更新机器人实战项目,欢迎各位订阅关注。 关注我,带你了解更多关于机器人、嵌入式、人工智能等方面的优质文章! 文章目录 一、项目背景二、国内外研究现状2.1 国内研究现状2.2 国外研究现状 三…...
QT-QTablewidget 设置选中某一行
要在 QTableWidget 中设置选中的行,可以使用 setCurrentItem() 函数来设置当前的 QTableWidgetItem。你可以通过调用 QTableWidget 的 item() 函数获得指定行和列的 QTableWidgetItem,然后通过将其传递给 setCurrentItem() 函数来设置选中的行。 下面是…...
[shell] 删除指定文件状态变更之前的文件及文件夹示例
参考文件 Linux查找某个指定时间要求的文件 脚本示例 #!/bin/bash# 删除指定时间之前文件,单位:分钟 ago75# 监控路径,必须使用使用绝对路径,防止意外删除重要文件 monitoring_path"/home/dev/test/test" # 使用find命令查找75分…...
代码中 isEmpty 和 isBlank 的区别
isEmpty系列 StringUtils.isEmpty() 是否为空. 可以看到 " " 空格是会绕过这种空判断,因为是一个空格,并不是严格的空值,会导致 isEmpty(" ")false tringUtils.isEmpty(null) true StringUtils.isEmpty("") true StringUtils.isEmpty(" …...

为什么要选择文件传输软件?有哪些最佳高速文件传输软件?
是否经历过这样的场景,正在努力地完成工作任务,但是由于制作的数据无法及时传送给合作伙伴,工作流程被打断了?这听起来很令人沮丧,对吧?可是,这种情况在现实中并不罕见。 因此,需要…...

aardio + customPlus 显示图片演示
看效果: 上代码: import win.ui; /*DSG{{*/ var winform win.form(text"aardio customPlus 显示图片演示 by 光庆";right927;bottom607) winform.add( button{cls"button";text"下一页";left664;top536;right794;bott…...

收集到大量的名片怎么转为excel?
来百度APP畅享高清图片 参加完展会或集体会议,是不是收了一大堆名片,保管起来超级麻烦,还容易丢三落四?别急,我们有办法!把名片转成电子版保存到电脑上就完美啦!但要是名片数量有点多࿰…...

JAVASE---方法的使用
方法概念及使用 什么是方法(method) 方法就是一个代码片段. 类似于 C 语言中的 "函数"。方法存在的意义(不要背, 重在体会): 1. 是能够模块化的组织代码(当代码规模比较复杂的时候)。 2. 做到代码被重复使用, 一份代码可以在多个位置使用。 3. 让代码更好理解更简单…...
CryptoJS.lib.WordArray.create、CryptoJS.enc.Base64介绍
1、CryptoJS.lib.WordArray.create:它是 CryptoJS 库中的一个方法,用于创建 WordArray 对象。WordArray 对象是 CryptoJS 库中用于处理二进制数据的基本数据类型。它通常用于表示加密算法的输入和输出。 2、CryptoJS.enc.Base64:它是 CryptoJ…...
linux 配置java环境变量
单个用户 vim ~/.bashrc 或者 vim ~/.bash_profile全局用户 vim /etc/profileexport JAVA_HOME/path/to/java export PATH$JAVA_HOME/bin:$PATH立即生效使用 source 命令 source ~/.bashrc source /etc/profilejava -version...

Mybatis异常Invalid bound statement (not found)原因之Mapper文件配置不匹配
模拟登录操作 $.post("/admin/login", {aname, pwd }, rt > {if (rt.code 200) {location.href "manager/index.html";return;}alert(rt.msg)});网页提示服务器代码错误 POST http://localhost:8888/admin/login 500后端显示无法找到Mapper中对应的…...

SAP中采购文档出现定价转换因子字段溢出是何原因?
近期处理了一笔用户反馈的主题问题。这个问题有意思的地方在于,多重错误的叠加,导致了问题在开始就暴露出来,可以将隐患消除在萌芽状态。 在公司的应用中,会由采购创建价格合同,物流参照价格合同创建计划协议。但采购…...

Linux6.33 Kubernetes kubectl详解
文章目录 计算机系统5G云计算第三章 LINUX Kubernetes kubectl详解一、陈述式资源管理方法1.基本信息查看2.项目的生命周期:创建-->发布-->更新-->回滚-->删除 二、声明式管理方法 计算机系统 5G云计算 第三章 LINUX Kubernetes kubectl详解 一、陈述…...
小程序uni-select溢出文字处理方式
<uni-data-select v-model="customFormData.limitedBy" :localdata="cancelWays" @change="change"></uni-data-select>溢出效果如下图...
【MacOS】mac OS 安装HP 打印机驱动 hp laserjet m1213nf mfp
先确认一下机器复印是否正常.确认一下打印机的硬件. 如果复印没问题 1. 下载v5.1集合包Hewlett-Packard 打印机驱动程序 v5.1.1 (OS X) (中国) 2. 苹果商城中,下载Pacifist,运行Pacifist,用Pacifist程序打开v5.1并安装 3. 电脑--系统偏好设置--打印…...
【搜索】DFS剪枝与优化
算法提高课笔记 目录 小猫爬山题意思路代码 数独题意思路代码 木棒题意思路代码 生日蛋糕题意思路代码 剪枝是什么意思呢? 我们知道,不管是内部搜索还是外部搜索,都可以形成一棵搜索树,如果将搜索树全部遍历一遍,效率…...

dfs之卒的遍历
题面 题目描述 在一张nm 的棋盘上(如 6 行 7 列)的最左上角(1,1) 的位置有一个卒。该卒只能向下或者向右走,且卒采取的策略是先向下,下边走到头就向右,请问从(1,1) 点走到 (n,m) 点可以怎样走,输出这些走法…...
Springboot整合activiti5,达梦数据库,mybatis中间件
Springboot整合activiti5,达梦数据库,mybatis中间件 问题现象解决方案 问题现象 由于工作流引擎不支持达梦数据库以及国产中间件,所以我们引入的时候会报错,这个时候就需要去改造代码和配置文件。各种文档和资料查找一天…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...

循环冗余码校验CRC码 算法步骤+详细实例计算
通信过程:(白话解释) 我们将原始待发送的消息称为 M M M,依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)(意思就是 G ( x ) G(x) G(x) 是已知的)࿰…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...

WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...

PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...
【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论
路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中(图1): mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...

GO协程(Goroutine)问题总结
在使用Go语言来编写代码时,遇到的一些问题总结一下 [参考文档]:https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现: 今天在看到这个教程的时候,在自己的电…...