【Qt】QSS
目录
一.基本语法
1.1.简单示例
1.2.样式的继承
1.3.设置全局样式
二.从文件加载样式表
2.1.方案一
2.2.方案二
三.选择器
3.1.常见选择器
3.2.简单示例
四.子控件
五.伪类选择器
六.样式属性
6.1.盒子模型介绍
6.2.简单示例
七.控件样式示例
7.1.给按钮设置样式
7.2.给复选框设置样式
7.3.给输入框设置样式
7.4.给列表框设置样式
7.5.Qlineargradient(线性渐变)
7.6.给菜单设置样式
7.7.给窗口设置背景图
在网页前端开发领域,CSS(层叠样式表)是不可或缺的核心技术之一,它负责描述网页的视觉呈现与样式效果。
所谓“样式”,涵盖了元素的尺寸、位置、颜色、背景、间距、字体等多方面属性,通过CSS的精确控制,能够有效美化页面,提升用户体验。
如今,几乎找不到没有使用CSS的现代网页。可以说,“界面美观”已成为用户和开发者的共同刚需。
网页开发作为图形用户界面(GUI)开发的典型代表,其设计理念也深刻影响了其他客户端GUI框架,Qt 正是其中之一。Qt 借鉴了CSS的设计思想,引入了 QSS(Qt Style Sheets),使开发者能够通过类似CSS的语法,对Qt控件进行样式设置,从而轻松构建更具吸引力的用户界面。
当然,由于Qt框架本身的设计理念与网页前端有所不同,QSS 仅支持CSS中的部分属性,整体语法更为简洁,上手难度也相对较低。即便没有CSS基础的同学,也能够较快掌握QSS的使用方法。
需要注意的是,在同时使用QSS和C++代码设置样式时,如果发生样式冲突,QSS的优先级高于C++代码中直接设置的样式属性,这一机制与Web中CSS的“层叠”特性保持一致。
一.基本语法
对于CSS来说,基本的语法结构⾮常简单.
选择器
{属性名: 属性值;
}
QSS 沿用了 CSS(层叠样式表)的基本语法设定,其基本结构如下:
选择器 {属性名: 属性值;
}
其中:
-
选择器 用于描述“哪些 widget 要应用该样式规则”,即指定一个或一类控件;
-
属性 为键值对形式,属性名表示需要设置的样式类别(如颜色、字体等),属性值则表示该样式具体的设定值。
例如,以下两种写法效果相同:
QPushButton { color: red; }
或
QPushButton {color: red;
}
上述规则的含义是:将界面中所有 QPushButton
的文本颜色设置为红色。
这种样式表机制使得开发者能够以声明式的方式统一管理界面控件的外观,提升代码的可维护性和视觉一致性。
1.1.简单示例
一个按钮
我们来编写程序
我们运行一下
当然,我们还可以使用rgb来表示颜色
两个或者多个按钮
如果我们多创建一个按钮,那么这个新创建的按钮会和上面一样显示对应的颜色吗
我们运行一下
我们发现按钮2的样式没有发生变化。
那么如果我们把代码修改成下面这个
我们运行一下
咋样。
1.2.样式的继承
在 QSS 中,“继承” 是一个核心概念。
当您将一个样式规则应用于某个容器控件(如 QWidget、QGroupBox、QFrame 等)时,这个样式不仅仅会影响该控件本身,还会自动向下传递给其内部的子控件。
这个设计理念源于这样一个基本原则:子控件通常被视为其父控件视觉环境的一部分。
因此,父控件所设定的基础视觉风格(如字体、颜色等),会自然地被子控件所沿用,以此来保证一个区域内视觉上的一致性。
我们修改一下代码
运行一下
2个按钮都变成红色了。
注意:我们设置的是"QPushButton { color: red }",只有按钮类的子控件的文本颜色才会变红。其他类型的子控件的颜色不会变化。
我们新增一个LineEdit
我们再次运行一下
我们发现我们的输入框里面的文字的颜色可不是红色啊。
1.3.设置全局样式
我们直接创建一个新的项目
我们运行一下
如果我们设置的全局样式,如果我们在某个控件设置了其他一个样式,会怎么样?
运行一下
我们发现按钮1在原有全局属性的设置下,另外设置了字体大小。
这个时候全局样式和其他样式会叠加起来。
如果通过全局样式给某个控件设置了属性1,通过指定控件样式给控件设置属性2,那么这两个属性都会 产⽣作⽤
形如上述这种属性叠加的效果,我们称为"层叠性". CSS全称为CascadingStyleSheets,其中Cascading就是"层叠性"的意思
QSS也继承了这 样的设定. 实际上把QSS叫做QCSS也许更合适⼀些~
如果我们设置的全局样式,如果我们在某个控件设置了其他一个样式,会怎么样?
我们运行一下
如果全局样式和指定控件样式冲突,则指定控件样式优先展⽰。
在CSS中也存在类似的优先级规则.通常来说都是"局部"优先级⾼于"全局"优先级.
相当于全局样式先"奠定基调",再通过指定控件样式来"特事特办".
二.从文件加载样式表
2.1.方案一
在目前的代码实现中,样式代码与 C++ 业务逻辑是直接混合编写的,例如:
ui->pushButton->setStyleSheet("QPushButton { color: #ffaa00; }");
如果所使用的 QSS 样式较为简单,这样的写法尚可接受。
然而,一旦QSS 样式代码变得复杂、规模增大,继续将样式与逻辑混在一起将会显著增加代码的维护难度,降低可读性,也不利于后期样式的统一调整。
为此,推荐将样式代码从 C++ 源码中分离出来,统一存放在独立的 QSS 文件中,再通过 C++ 代码加载并应用到应用程序中。这种资源管理方式不仅结构清晰,也便于多主题切换或样式动态更新。
我们创建一个项目
接下来我们把QSS样式的代码写到一个.qss文件里面,然后我们再创建一个qrc文件,把这个.qss文件放到我们的qrc文件,然后我们再通过C++的文件读取功能来获取这个.qss代码。
创建出来之后把它的名字改一改
添加一下,并且将QSS文件修改成下面这个
接着我们写一下代码
运行一下
我们回去那个style.qss里面修改成green看看
再次运行一下
很好是是。不过在实际开发中,QT还提供了更方便的办法。
2.2.方案二
Qt Designer 中直接集成这样的功能,允许我们把样式直接写到 .ui 文件里
通过这里我们就可以编写我们界面的样式。
通过这里就可以编写界面的样式了
这里进行的修改都会记录到 ui 文件中并且在程序运行时自动生效,而且这里还能进行预览~
就比如说,我把下面这个给写进去看看
QPushButton {/* 基本样式 */background-color: #4CAF50; /* 主色调 - 绿色 */border: 2px solid #45a049; /* 边框 */border-radius: 8px; /* 圆角 */color: white; /* 文字颜色 */font-family: "Microsoft YaHei", sans-serif; /* 字体 */font-size: 14px;font-weight: bold;padding: 8px 16px; /* 内边距 */min-width: 80px; /* 最小宽度 */min-height: 30px; /* 最小高度 *//* 渐变背景 */background: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 #6BBF70, stop:1 #4CAF50);/* 文字阴影 */text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
}
左下角他会自动帮我们校验格式是否正确!!
我们点击OK,发现按钮的样式就会实时显示到那里看看
怎么样?这个按钮是不是很好看啊。
隐患
由于 Qt 中设置样式的方式非常灵活,同一控件的样式可能来源于多个不同层级,一旦某个控件的显示效果不符合预期,定位问题来源就会变得比较困难。
常见的样式设置来源包括:
-
全局样式:通过
QApplication::setStyleSheet()
设置的样式,会影响应用程序中的所有控件。 -
控件自身样式:直接对控件调用
setStyleSheet()
设置的样式,仅作用于该控件本身。 -
父控件样式继承:控件可能从其父控件继承样式规则,特别是在父控件设置了样式表且未明确限制作用范围的情况下。
-
外部 QSS 文件:通过读取外部 QSS 文件设置的样式,一般用于统一管理多个样式规则。
-
UI 文件中设置的样式:在 Qt Designer 或 Qt Creator 的 UI 文件中直接为控件设置的样式表。
在实际开发中,如果样式设置来源不统一,很容易造成样式冲突或覆盖,增加调试复杂度。因此,建议在项目中约定一种主要的样式设置方式,并尽量避免多层级混合设置。例如,可以统一使用 QSS 文件进行样式管理,或在代码中集中设置样式,以减少不一致性并提升可维护性。
三.选择器
3.1.常见选择器
下面我将详细解释每一种选择器,并给出示例。
1.全局选择器 (Universal Selector)
-
符号:
*
-
说明:这个选择器会匹配所有的控件(widget)。使用它时,设置的样式将应用于应用程序中的每一个控件。
-
示例:
* { color: red; }
这会将所有控件的前景色(文字颜色)设置为红色。
2.类型选择器 (Type Selector)
-
示例:
QPushButton
-
说明:这个选择器会选择所有指定类型的控件及其子类。例如,
QPushButton
会选择所有QPushButton
以及从QPushButton
继承的子类(如MyPushButton
,如果你定义了一个这样的子类)的控件。 -
示例:
QPushButton { background-color: blue; }
这会将所有
QPushButton
及其子类的背景色设置为蓝色。
3.类选择器 (Class Selector)
-
示例:.QPushButton
-
注意不要忘了类名前面那一个点!!!
-
说明:这个选择器只会选择指定类的控件,而不会包括其子类。注意,这里的类指的是控件的确切类型,不包含继承。在Qt中,控件的类名就是其C++类名。
-
示例:
.QPushButton { background-color: green; }
这只会将确切类型为
QPushButton
的控件背景色设置为绿色,而不会影响其子类。
4.ID 选择器 (ID Selector)
-
示例:
#pushButton_2
-
说明:这个选择器会选择具有指定 objectName 的控件。在Qt中,你可以通过 setObjectName 方法为控件设置一个唯一的标识符。注意,objectName 是区分大小写的。
-
示例:
#pushButton_2 { color: yellow; }
这会将
objectName
为pushButton_2
的控件的文字颜色设置为黄色。
5.后代选择器 (Descendant Selector)
-
示例:
QDialog QPushButton
-
说明:这个选择器会选择所有在
QDialog
内部(即作为后代,包括子控件、孙控件等)的QPushButton
。注意,不要求QPushButton
是直接子控件,只要在QDialog
的控件树中即可。 -
示例:
QDialog QPushButton { font-weight: bold; }
这会将所有在
QDialog
中的QPushButton
(无论嵌套多深)的字体设置为粗体。
6.子选择器 (Child Selector)
-
示例:
QDialog > QPushButton
-
说明:这个选择器只会选择
QDialog
的直接子控件中的QPushButton
。注意,它只匹配直接子控件,不会匹配孙控件或更深的控件。 -
示例:
QDialog > QPushButton { border: 1px solid black; }
这会将所有作为
QDialog
直接子控件的QPushButton
的边框设置为1像素宽的黑色实线。
7.并集选择器 (Grouping Selector)
-
语法:
选择器1, 选择器2, 选择器3
功能: 同时选择多个不同类型的控件,对它们应用相同的样式。
-
示例:
QPushButton, QLineEdit, QComboBox
-
说明:这个选择器可以同时选择多种类型的控件,并将相同的样式规则应用于它们。每个选择器之间用逗号分隔。
-
示例1:
QPushButton, QLineEdit, QComboBox {border: 1px solid gray; }
这个选择器会影响到:
QPushButton 及其所有子类
QLineEdit 及其所有子类
QComboBox 及其所有子类
因为类型选择器本身就包含子类。
-
示例2:
.QPushButton, .QLineEdit, .QComboBox {border: 1px solid gray; }
这个选择器只会影响到:
确切的 QPushButton 类(不含子类)
确切的 QLineEdit 类(不含子类)
确切的 QComboBox 类(不含子类)
-
示例3
QPushButton, .QLineEdit, #myButton {background-color: blue; }
这个选择器会影响到:
QPushButton 及其所有子类(类型选择器)
确切的 QLineEdit 类,不含子类(类选择器)
objectName 为 "myButton" 的特定控件(ID选择器)
8.属性选择器 (Attribute Selector)
-
示例:
QPushButton[flat="false"]
-
说明:这个选择器会选择具有特定属性且该属性等于指定值的控件。注意,这里的属性是Qt属性,而不是CSS属性。你可以通过
property()
和setProperty()
方法来访问和设置这些属性。在QSS中,你可以根据这些属性的值来设置样式。 -
示例:
QPushButton[flat="false"] { background-color: cyan; }
这会将所有
flat
属性为false
的QPushButton
的背景色设置为青色。
注意:在使用属性选择器时,属性名和值都是区分大小写的。
以上就是QSS中常用的选择器类型。使用这些选择器,你可以精确地定位到需要设置样式的控件,从而实现复杂的界面样式设计。
3.2.简单示例
我们创建一个新的项目
我们创建一个项目
接下来我们就来设置样式
类型选择器
这个选择器会选择所有指定类型QPushButton的控件及其子类。
我们的QPushButton没有子类啊,怎么验证呢?
我们把选择器修改为QWidget,也就是QPushButton的父类
还是影响到了,如果我们把选择器换成下面这个
则不会影响到QWidget的子类,它只针对QWidget生效
我们修改一下.ui文件
运行一下,我们看看
此时当类型选择器和 id 选择器选中同一个控件的时候,并且设置的样式是冲突的,此时,id 选择器的优先级更高。
如果不冲突,两种样式都会同时生效~~
我们修改一下.ui文件
我们修改一下代码
咋样,都进行设置了。
我们再修改一下
还行吧。
四.子控件
想象一下一个复杂的控件,比如 QComboBox
(组合框)或 QSpinBox
(数字旋转框)。它们并不是一个单一的、简单的矩形。相反,它们是由多个更小的、功能各异的“部件”组合而成的。
-
QComboBox
:通常包含一个显示当前文本的“矩形框”,和一个用于展开下拉列表的“下拉箭头按钮”。 -
QSpinBox
:通常包含一个显示数字的“文本框”,和一个用于增加数值的“上箭头按钮”,以及一个用于减少数值的“下箭头按钮”。
这些内部的“小部件”(如下拉箭头、上下按钮)就是所谓的 子控件。
子控件选择器 就是 Qt 样式表中提供的一种特殊语法,允许你像“外科手术”一样,精准地定位到这些内部的子控件,并单独为它们设置样式,而不会影响到控件的其他部分。
子控件选择器的语法非常直观,使用两个冒号 :: 来连接 主控件 和 子控件。
主控件类型::子控件名称 {属性: 值;属性: 值;...
}
我们可以去官方文档里面看看哪些控件是具有子控件的。参考⽂档Qt Style Sheets Reference中List of Sub-Controls章节.
这里就有很多子控件。
示例1——设置下拉框的下拉按钮样式
我们创建一个新项目
我们双击它
点击OK
我找了下面这个图标
接下来我们创建qrc文件
我们去编写一下代码
这个QSS代码的意思就是
“把所有 QComboBox(下拉选择框)右侧的那个小小的、用来点击展开列表的【向下箭头图标】,替换成我自定义的一张图片。”
我们来拆解一下:
- QComboBox:这是我们要打扮的“角色”,即下拉选择框控件。
- ::down-arrow:这是一个“子控件”选择器。它特指 QComboBox 身上的向下箭头部分,而不是整个下拉框。
- image: url(...);:这是一个 QSS 属性,用于设置元素的背景图像。
- :/test.png:这是图片的路径。: 开头通常表示这张图片被存储在 Qt 程序的资源文件 里,名字叫做 test.png。
运行一下
怎么样?这个下拉按钮还满意吗?
五.伪类选择器
伪类选择器,是根据控件所处的某个状态被选择的
例如按钮被按下,输⼊框获取到焦点,⿏标移动到某 个控件上等.
- 当状态具备时,控件被选中,样式⽣效.
- 当状态不具备时,控件不被选中,样式失效.
使⽤ : 的⽅式定义伪类选择器
你可以把这些伪类选择器理解为根据用户的操作或控件自身的状态,来给控件穿上不同的“衣服”。当控件处于某个特定状态时,对应的样式就会生效;状态一改变,样式就失效了。
下面是每个选择器的详细说明:
1. :hover
-
解释:当用户的鼠标光标悬停在控件上方时,这个状态就会被触发。
-
生活化比喻:就像你把手指向桌子上的一杯水,你还没有碰到它,但你的注意力已经在它上面了。控件通常会对这个状态做出反应,比如改变颜色或出现阴影,以提示用户“这个是可以点击的”。
-
示例场景:鼠标移到一个按钮上,按钮背景色变亮。
2. :pressed
-
解释:当用户在控件上按下鼠标左键(但还未松开) 时,控件处于这个状态。
-
生活化比喻:就像你用手按下一个真实的物理按钮,它被按下去了一半,但还没弹起来。这个状态通常用来模拟被按下的物理效果。
-
示例场景:点击按钮的瞬间,按钮背景色变暗或看起来被“按”进去了。
3. :focus
-
解释:当控件获取到输入焦点时,处于这个状态。通常是通过键盘(如 Tab 键)切换或直接用鼠标点击控件来获得。
-
生活化比喻:就像几个人在开会,只有那个正在发言的人面前的话筒是打开的,他成为了会议的“焦点”。带焦点的控件是当前准备接收键盘输入的那个。
-
示例场景:一个输入框被点击后,周围出现一个蓝色的边框,表示你可以在里面打字了。
4. :enabled 与 :!enabled (或 :disabled)
-
解释:
-
:enabled
:当控件处于可用状态时。大多数控件默认都是可用的。 -
:!enabled
或:disabled
:当控件处于不可用(禁用)状态时。
-
-
生活化比喻:就像一个电灯开关。当开关处于“开”的状态(
:enabled
),你可以按它来控制灯。当开关被用保护罩盖住了(:disabled
),你就无法操作它。 -
示例场景:一个灰色的、无法点击的“提交”按钮。
5. :checked
-
解释:这个状态主要用于可以勾选的控件,当它们被选中时触发。
-
生活化比喻:就像你购物清单上的一个复选框,你在它里面打上了勾。
-
示例场景:一个单选按钮(Radio Button)或多选框(Check Box)被选中时的样式。
6. :read-only 与 :!read-only
-
解释:
-
:read-only
:当控件(通常是文本输入类)的内容只能读取,不能修改时。 -
:!read-only
:当控件内容可以修改时。
-
-
生活化比喻:博物馆里放在玻璃罩里的展品说明书是只读的(
:read-only
),而你自己的笔记本是可以随意涂写的(:!read-only
)。 -
示例场景:一个显示配置信息的输入框,背景是灰色的,表示你不能编辑它。
关于取反操作
!
它的作用就是选择“不处于”该状态的控件。
-
:!hover
:当鼠标没有悬停在控件上时(即鼠标离开时)生效。 -
:!pressed
:当鼠标没有按下时(即松开状态)生效。 -
:!checked
:当控件未被勾选时生效。 -
:!focus
:当控件没有获得输入焦点时生效。
当然,我这里只是举了一些比较简单的伪类选择器
想要了解更多,可以去官方文档里面看看
还是有很多伪类选择器的
我们创建一个项目,先去.ui文件里面放一个QPushButton
我们运行一下
我们把鼠标悬停在按钮上
我们发现这个文字颜色变绿了。
我们按下这个按钮(注意按着不放)
我们发现里面的文字变成了蓝色。
当然,上面这些我们都能通过事件的方式来实现的,但是完全没有我们的伪类选择器好用。我就不演示了。
六.样式属性
QSS中的样式属性⾮常多,不需要都记住.核⼼原则还是⽤到了就去查.
⼤部分的属性和CSS是⾮常相似的
⽂档的 Qt Style Sheets Reference 章节详细介绍了哪些控件可以设置属性,每个控 件都能设置哪些属性等.
大家在翻阅文档的时候很容易就看到一个词
我们把它叫盒子模型。
6.1.盒子模型介绍
我们可以在文档里面直接点击这个盒子模型,就能跳转它的文档里面
我们就来讲讲这个盒子模型
在使用样式表进行界面设计时,每一个控件均可视为一个由四个同心矩形构成的容器,依次为:外边距矩形、边框矩形、内边距矩形和内容矩形。
这一结构在网页与界面设计中被称为“盒子模型”(Box Model),它详细规范了控件在视觉上的空间组成方式。
盒子模型的四个矩形区域从外到内依次排列,其概念结构可参考以下示意图:
(此处保留原图示位置)
-
外边距(Margin):位于盒模型的最外层,是边框之外的空间,主要用于控制当前控件与相邻元素之间的距离。
-
边框(Border):紧邻外边距内侧,是围绕在内边距和内容外部的可见边界,可设置宽度、样式与颜色。
-
内边距(Padding):位于边框内侧,是内容区域与边框之间的缓冲区域,常用来调节内容与边框之间的间距,增强可读性与美观性。
-
内容区域(Content):处于盒模型的最内层,是实际承载文本、图像或子控件等内容的区域。其尺寸为原始控件尺寸依次减去外边距、边框及内边距后所剩余的空间。
理解盒模型的结构对于精确控制控件尺寸、定位及整体布局至关重要,也是实现一致且可控的界面样式的基础。
默认情况下,外边距,内边距,边框宽度都是0.
可以通过⼀些QSS属性来设置上述的边距和边框的样式
1. margin(外边距)
通俗解释: 一个控件之外的透明区域。
它决定了这个控件和它的“邻居”(其他控件或者窗口边缘)之间应该保持多大的距离。你可以把它想象成一个人周围的“个人空间”或者一幅画与画框外其他物品之间的空隙。
作用: 控制控件外部的间距,用于布局和控件间的排列。
属性值: 通常是像素(px),例如 5px。
用法:
- margin: 5px; —— 一个值:表示上下左右四个方向的外边距都是5像素。
- margin: 5px 10px; —— 两个值:第一个值代表上下外边距(5px),第二个值代表左右外边距(10px)。
- margin: 5px 10px 15px 20px; —— 四个值:分别代表上、右、下、左四个方向的外边距(按顺时针方向)。
示例:
假设有两个并排的按钮,如果没有外边距,它们会紧挨在一起。如果你给它们设置了 margin: 10px;,那么每个按钮的四周都会空出10像素的距离,它们之间、它们与窗口边缘之间就分开了。
2. padding(内边距)
通俗解释: 控件内容与控件边框之间的透明区域。它决定了控件内部的文字、图标等内容,距离控件自己的边框有多远。你可以把它想象成画框的“内衬”或者一个房间的“墙壁和家具之间的过道”。
作用: 控制控件内部的间距,用于改善内容的可读性和美观度。
属性值: 同样是像素(px),例如 10px。
用法:
- 和 margin 的规则完全一样,可以设置1个、2个或4个值。
- padding: 10px; - 内容距离边框四周都是10像素。
示例:
一个按钮上的文字“确定”,如果没有内边距,文字会紧贴着按钮的边,看起来很拥挤。如果你设置了 padding: 8px 15px;,那么文字上下会有8像素的空间,左右会有15像素的空间,按钮看起来就会饱满、舒适很多。
margin 和 padding 的核心区别(非常重要!)
用一个带相框的照片来比喻:
- 整个控件 = 照片+相框+相框外的空间。
- 内容 = 照片本身。
- 边框(border) = 相框的木条。
- padding = 照片和相框木条之间的那圈卡纸。
- margin = 这个相框和墙上其他相框或者家具之间的距离。
简单记:padding 是“内功”,扩大的是控件自己的体积;margin 是“外功”,推开的是周围的其他东西。
3. 边框(Border)属性
边框就是围绕在控件内容和内边距之外的一条线。它由三个主要属性构成,并且通常用一个复合属性来简化设置。
a) border-style(边框样式)
通俗解释: 边框的线条类型。
常用值:
- none - 无边框(默认)。
- solid - 实线(最常用)。
- dashed - 虚线。
- dotted - 点线。
- double - 双线。
b) border-width(边框宽度)
通俗解释: 边框的粗细。
常用值: 像素(px),例如 2px。
c) border-color(边框颜色)
通俗解释: 边框的颜色。
常用值: 颜色名(如 red),十六进制值(如 #FF0000),RGB值(如 rgb(255, 0, 0))。
4. border(边框复合属性)
通俗解释: 这是一个“快捷方式”属性,可以让你一次性设置边框的样式、宽度和颜色,而不用写三行代码。
语法: border: <width> <style> <color>;
顺序: 这三个值的顺序可以互换,但通常按照 宽度 样式 颜色 的顺序来写。
用法:
- border: 2px solid red; - 设置一个2像素宽的红色实线边框。
- border: none; - 移除所有边框。
注意: 使用 border 复合属性会同时设置四个方向的边框。如果你想单独设置某一个方向的边框(例如只要一个底部边框),可以使用 border-bottom,border-top,border-left,border-right 属性,用法和 border 一样。
6.2.简单示例
示例1——设置边框,内边距
我们创建一个项目,先搞一个QLabel来
我们编写一下代码
"border: 5px solid red; "
- border: - 边框的复合属性
- 5px - 边框宽度为5像素
- solid - 边框样式为实线(其他可选值:dashed虚线、dotted点线等)
- red - 边框颜色为红色(也可以用十六进制值如#FF0000)
这行代码相当于同时设置了:border-width: 5px; + border-style: solid; + border-color: red;
"padding-left: 5px; "
- padding-left: - 只设置左侧的内边距
- 5px - 左侧内边距为5像素
这意味着QLabel中的文字/内容会距离左边框有5像素的空白区域
我们运行一下
我们发现文字就没有贴着左边的边框的显示了。
我们可以再次修改一下代码
"border: 20px solid red; "
- border: - 边框的复合属性
- 20px - 边框宽度为20像素
- dashed - 边框样式为虚线
- green - 边框颜色为绿色
这行代码相当于同时设置了:border-width: 20px; + border-style: dashed; + border-color: green;
示例2——设置外边距
我们
运行一下
现在我们就来设定一下样式。
运行一下
我们仔细看看一下,我们这个按钮好像变小了啊。我们可以验证一下
我们看到这个按钮没有变小啊。
我们看看,事实上外边距其实也算是这个控件的一部分,外边距大了,我们这个按钮就看起来就小了。
从视觉设计的角度来看,外边距是控件所占空间的一部分。
当外边距增大时,按钮本身的可视区域在整体空间中的占比就会减小,从而导致其视觉权重降低,给人感觉按钮“变小”了。
七.控件样式示例
7.1.给按钮设置样式
我们直接创建新项目,来到.ui文件
QPushButton {/* 基本样式 */background-color: #4CAF50;border: 2px solid #4CAF50; /* 添加边框 */color: white;padding: 12px 24px;text-align: center;font-size: 16px;font-weight: bold;border-radius: 8px;/* 渐变效果 */background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 #6BBF70, stop: 1 #4CAF50);/* 阴影效果 */box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);/* 最小尺寸 */min-width: 120px;min-height: 40px;/* 添加过渡效果 */transition: all 0.2s ease;
}/* 鼠标悬停效果 - 更明显的改变 */
QPushButton:hover {background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 #7ECF82, stop: 1 #5CB860);border: 2px solid #5CB860;box-shadow: 0 6px 12px rgba(0, 0, 0, 0.3);transform: translateY(-2px); /* 向上轻微移动 */
}/* 按下效果 - 与悬停完全不同的风格 */
QPushButton:pressed {background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 #3d8b40, stop: 1 #2E7D32);border: 2px solid #2E7D32;box-shadow: inset 0 4px 8px rgba(0, 0, 0, 0.4); /* 内阴影,模拟凹陷 */transform: translateY(1px); /* 向下移动 */color: #E8F5E9; /* 文字颜色变浅 */
}
注意:上面的类似于#9bd4ff,#fdff80是从下面这个选色器里面来的
我们看看
还是很不错的吧。
我们运行一下
按下
颜色更黑了一点
7.2.给复选框设置样式
我们创建一个项目
我们这里准备了3组
其中我们让左边作为未选择的状态,右边则作为选择的状态
-
checkbox-unchecked-pressed.png
-
checkbox-unchecked-hover.png
-
checkbox-unchecked.png
-
checkbox-checked.png
-
checkbox-checked-hover.png
-
checkbox-checked-pressed.png
注意:我已经把这些资源放到了项目里面
接下来我们创建.qrc文件
添加一下
我们现在先不着急写QSS代码,我们先来复习一下
1. ::indicator (子控件选择器)
-
它是什么? 这是一个“子控件选择器”。在 Qt 中,一个复杂的控件(如
QCheckBox
)是由多个部分组成的。QCheckBox
不仅仅是一个对钩,它通常还包括一个放对钩的小方框(指示器)和旁边的文字标签。 -
它做什么用?
::indicator
就是用来专门选中那个放对钩的小方框部分的。当你想要改变这个方框的大小、背景、边框或者对钩图片时,就需要用它来“瞄准”这个特定区域。 -
比喻: 如果把整个
QCheckBox
看作一个人,那么::indicator
就是专门用来给这个人的“帽子”做造型的,而不会影响到他的“脸”或“衣服”(文字标签部分)。
示例代码:
QCheckBox::indicator {width: 20px;height: 20px;border: 2px solid gray;background-color: white;
}
这段代码会把所有复选框的小方框变成 20x20 像素,带灰色边框和白色背景。
2. :hover (伪类选择器)
-
它是什么? 这是一个“伪类选择器”。它不描述控件的某个物理部分,而是描述控件的一种状态。
-
它做什么用?
:hover
用于选中当鼠标光标悬停在控件上方时的状态。你可以用它来设置鼠标放上去时的特殊效果,比如改变颜色、边框等,提供视觉反馈。
示例代码:
QCheckBox:hover {color: blue; /* 鼠标悬停时,文字变成蓝色 */
}QCheckBox::indicator:hover {border: 2px solid blue; /* 鼠标悬停在那个小方框上时,方框边框变蓝 */
}
3. :pressed (伪类选择器)
-
它是什么? 同样是“伪类选择器”。
-
它做什么用?
:pressed
用于选中当鼠标在控件上被按下(但还未释放)时的状态。这通常用来模拟按钮被按下去的效果。
示例代码:
QCheckBox::indicator:pressed {background-color: lightgray; /* 鼠标在小方框上按下时,方框背景变成浅灰色 */
}
4. :checked (伪类选择器)
-
它是什么? “伪类选择器”。
-
它做什么用?
:checked
用于选中已经被选中(勾选)的控件。这是定制复选框、单选框时最常用的伪类之一。
示例代码:
QCheckBox::indicator:checked {background-color: green; /* 被选中的复选框,其小方框背景为绿色 */
}
5. :unchecked (伪类选择器)
-
它是什么? “伪类选择器”。
-
它做什么用?
:unchecked
用于选中未被选中(未勾选)的控件。它和:checked
是相反的状态。
示例代码:
QCheckBox::indicator:unchecked {background-color: white; /* 未选中的复选框,其小方框背景为白色 */
}
6. width 和 7. height
-
它们是什么? 用于设置子控件尺寸的属性。
-
特别注意(非常重要!):
width
和height
对于普通控件(如QPushButton
,QLabel
)是无效的,因为这些控件的尺寸通常由布局管理器或其geometry
决定。但是,对于::indicator
这样的子控件,或者QSpinBox
的上下箭头、QComboBox
的下拉箭头等,你必须使用width
和height
来改变它们的大小。
示例代码:
/* 这个会生效,因为目标是子控件 */
QCheckBox::indicator {width: 30px;height: 30px;
}/* 这个可能不会按预期生效,最好用 min-width/min-height 或通过布局设置 */
QPushButton {width: 100px; /* 不推荐这样做 */height: 50px; /* 不推荐这样做 */
}
8. image
-
它是什么? 一个属性,用于为子控件设置图片。
-
它做什么用? 它可以用来用自定义图片替换掉控件默认的样式。例如,你可以把
QCheckBox
的对钩换成一张自定义的图片,或者把QSpinBox
的上下箭头换成更漂亮的图标。
示例代码:
/* 为被选中的复选框的指示器设置一个自定义的对钩图片 */
QCheckBox::indicator:checked {image: url(checked.png);
}/* 为未选中的复选框的指示器设置一个自定义的空框图片 */
QCheckBox::indicator:unchecked {image: url(unchecked.png);
}
好了,学习完上面那些,我们就能写出下面这个
QCheckBox {/* 设置复选框文本的字体大小为20像素 */font-size: 20px;
}QCheckBox::indicator {/* 设置复选框指示器(勾选框)的尺寸为20x20像素 */width: 20px;height: 20px;
}QCheckBox::indicator:unchecked {/* 未选中状态下的默认图标 */image: url(:/resource/checkbox-unchecked.png);
}QCheckBox::indicator:unchecked:hover {/* 未选中状态下鼠标悬停时的图标 */image: url(:/resource/checkbox-unchecked-hover.png);
}QCheckBox::indicator:unchecked:pressed {/* 未选中状态下鼠标按下时的图标 */image: url(:/resource/checkbox-unchecked-pressed.png);
}QCheckBox::indicator:checked {/* 选中状态下的默认图标 */image: url(:/resource/checkbox-checked.png);
}QCheckBox::indicator:checked:hover {/* 选中状态下鼠标悬停时的图标 */image: url(:/resource/checkbox-checked-hover.png);
}QCheckBox::indicator:checked:pressed {/* 选中状态下鼠标按下时的图标 */image: url(:/resource/checkbox-checked-pressed.png);
}
我们点击确定
我们运行一下
鼠标悬停在这个复选框上
鼠标按下,不松手
然后把鼠标移开
鼠标悬停在这个复选框
鼠标按下不松手
7.3.给输入框设置样式
我们创建一个例子
我们直接放入
QLineEdit {/* 设置边框宽度为1像素 */border-width: 1px; /* 设置边框圆角半径为10像素 */border-radius: 10px;/* 设置边框颜色为RGB(58,58,58) - 深灰色 */border-color: rgb(58, 58, 58);/* 设置边框样式为凹陷效果 */border-style: inset;/* 设置内边距:上下为0,左右为8像素 */padding: 0 8px;/* 设置文字颜色为白色 */color: rgb(255, 255, 255);/* 设置背景颜色为RGB(100,100,100) - 中灰色 */background: rgb(100, 100, 100);/* 设置选中文本的背景颜色为RGB(187,187,187) - 浅灰色 */selection-background-color: rgb(187, 187, 187);/* 设置选中文本的文字颜色为RGB(60,63,65) - 深灰色 */selection-color: rgb(60, 63, 65);
}
这些属性是Qt样式表(QSS)中常用的属性,用于自定义控件的外观。下面我将逐一解释每个属性的作用和用法。
1. border-width - 边框宽度
作用:设置控件边框线条的粗细。
就像:给一幅画选择画框的粗细。
示例:
- border-width: 2px; → 边框宽度为 2 像素。
- border-width: 1px 2px 3px 4px; → 分别设置上、右、下、左四个方向的边框宽度(顺时针顺序)。
2. border-radius - 边框圆角
作用:设置控件四个角的圆润程度。数值越大,角越圆。
就像:把方形的桌角磨圆。
示例:
- border-radius: 5px; → 四个角都是 5 像素的圆角。
- border-radius: 10px 0px; → 左上角和右下角为10px,右上角和左下角为0px(依然是方形)。
3. border-color - 边框颜色
作用:设置边框的颜色。
就像:选择画框的颜色。
示例:
- border-color: red; → 红色边框。
- border-color: #FF0000; → 用十六进制代码也表示红色。
4. border-style - 边框风格
作用:设置边框的线条样式,比如是实线、虚线还是点线。
就像:选择画框是实木的(实线)还是由一段段木条拼接的(虚线)。
常用值:
- solid:实线(最常用)
- dashed:虚线
- dotted:点线
- none:无边框
5. padding - 内边距
作用:设置控件内容(比如文字)与控件边框之间的空白区域的大小。
就像:给相框里的照片加上卡纸,让照片和框之间有一段距离。
示例:
- padding: 5px; → 内容与边框四周都有 5 像素的间隔。
- padding: 2px 5px; → 上下内边距为2px,左右内边距为5px。
6. color - 文字颜色
作用:设置控件内文本的颜色。
就像:用哪种颜色的墨水写字。
示例:
- color: white; → 白色文字。
- color: rgba(255, 255, 255, 0.8); → 白色文字,且80%不透明(带透明度)。
7. background - 背景
作用:设置控件的背景,可以是颜色,也可以是图片。
就像:给一幅画铺上背景色或背景图案。
示例:
- background: blue; → 蓝色背景。
- background: url(:/images/texture.png); → 使用图片作为背景。
8. selection-background-color - 选中文字的背景色
作用:当你在控件中用鼠标选中一部分文字时,被选中文字背后的背景色。
就像:你用荧光笔划重点时,笔迹的颜色。
示例:
selection-background-color: #367EFB; → 选中文字的背景是蓝色(很多现代应用的默认色)。
9. selection-color - 选中文字的文本颜色
作用:当你在控件中用鼠标选中一部分文字时,被选中文字本身的颜色。
就像:你划重点时,重点文字本身变成什么颜色。
示例:
selection-color: white; → 选中文字的颜色变为白色。通常与深色的 selection-background-color 搭配使用,形成高对比度,方便阅读。
我们看到实时显示了
我们运行一下
输入一些文字
我们选中这些文字
7.4.给列表框设置样式
1. ::item - 项选择器
这是最基础的选择器,用于选择 QListWidget 中的每一个具体项目。
QListWidget::item {padding: 5px; /* 内边距 */margin: 2px; /* 外边距 */height: 30px; /* 项高度 */
}
2. :hover - 悬停状态
当鼠标悬停在项目上时应用的样式:
QListWidget::item:hover {background-color: #e0e0e0; /* 悬停时的背景色 */color: #333; /* 悬停时的文字颜色 */
}
3. :selected - 选中状态
当项目被选中时应用的样式:
QListWidget::item:selected {background-color: #0078d4; /* 选中时的背景色 */color: white; /* 选中时的文字颜色 */
}
4. background - 背景设置
设置元素的背景,可以是颜色或渐变:
/* 纯色背景 */
QListWidget::item {background: #f5f5f5;
}/* 或者分开设置 */
QListWidget::item {background-color: #f5f5f5;
}
5. border - 边框设置
设置元素的边框样式:
QListWidget::item {border: 1px solid #ccc; /* 1像素宽的灰色实线边框 */border-radius: 3px; /* 圆角边框 */
}/* 也可以分开设置 */
QListWidget::item {border-width: 1px;border-style: solid;border-color: #ccc;
}
好了,我们现在就来看看
我们创建一个新项目
我们双击它,并添加下面这些项
/* QListView 项悬停效果 */
QListView::item:hover {/* 线性渐变背景 - 从上到下 */background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 #FAFBFE, /* 顶部颜色 - 浅灰色 */stop: 1 #DCDEF1); /* 底部颜色 - 略深的灰色 */
}/* QListView 项选中状态 */
QListView::item:selected {/* 边框设置 */border: 1px solid #6a6ea9; /* 紫色边框 *//* 线性渐变背景 - 从上到下 */background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 #6a6ea9, /* 顶部颜色 - 深紫色 */stop: 1 #888dd9); /* 底部颜色 - 亮紫色 */
}
我们运行一下
鼠标悬停
鼠标按下
7.5.Qlineargradient(线性渐变)
我们上面使用了线性渐变。
我们来看看
Qlineargradient(线性渐变)的核心思想是:沿着一条假想的直线,颜色发生平滑的过渡。
您可以把它想象成一根彩色的“标尺”,标尺的起点是一种颜色,终点是另一种颜色,中间的部分就是这两种颜色混合出来的过渡色。
qlineargradient 有6个参数.
这六个参数共同定义了这根“彩色标尺”的位置、方向和颜色。
1. 定义方向:(x1, y1) 和 (x2, y2)
-
(x1, y1): 这是渐变的起点。
-
(x2, y2): 这是渐变的终点。
关键点:
-
这两个点定义的向量 (x2-x1, y2-y1) 指明了渐变的方向。
-
渐变的颜色变化,就是沿着从 (x1, y1) 指向 (x2, y2) 的方向进行的。
-
这两个点的坐标不是绝对的像素坐标,而是相对于一个“坐标系”的。这个坐标系默认是 0 到 1 的归一化坐标系。
-
(0, 0)
代表要绘制渐变区域的左上角。 -
(0, 1)
代表要绘制渐变区域的左下角。 -
(1, 0)
代表要绘制渐变区域的右上角。 -
(1, 1)
代表要绘制渐变区域的右下角。 -
使用这种坐标系的好处是,无论你的矩形区域是 100x100 还是 500x500,渐变都会自动按比例适应。
-
-
在 0-1 坐标系下:
-
垂直向下渐变 (x1:0, y1:0, x2:0, y2:1)
-
起点在左上角
(0,0)
。 -
终点在左下角
(0,1)
。 -
这两个点定义的向量 (x2-x1, y2-y1) 指明了渐变的方向。
-
方向向量是
(0, 1)
,即垂直向下。 -
所以颜色从顶部的
stop0
到底部的stop1
渐变。
-
-
水平向右渐变 (x1:0, y1:0, x2:1, y2:0)
-
起点在左上角
(0,0)
。 -
终点在右上角
(1,0)
。 -
这两个点定义的向量 (x2-x1, y2-y1) 指明了渐变的方向。
-
方向向量是
(1, 0)
,即水平向右。 -
所以颜色从左边的
stop0
到右边的stop1
渐变。
-
-
对角线渐变 (x1:0, y1:0, x2:1, y2:1)
-
起点在左上角
(0,0)
。 -
终点在右下角
(1,1)
。 -
这两个点定义的向量 (x2-x1, y2-y1) 指明了渐变的方向。
-
方向向量是
(1, 1)
,即从左上到右下。 -
所以颜色从左上角的
stop0
到右下角的stop1
渐变。
-
2. 定义颜色:stop0 和 stop1
-
stop(停靠点):它描述在渐变路径上的某个位置应该是什么颜色。
-
停靠点的位置也是一个 0 到 1 之间的值。
-
0.0
对应着渐变的起点 (x1, y1)。 -
1.0
对应着渐变的终点 (x2, y2)。 -
0.5
则对应着起点和终点正中间的位置。
-
所以,stop0
和 stop1
通常指的是两个停靠点:
-
stop0: 通常是在位置
0.0
的颜色。 -
stop1: 通常是在位置
1.0
的颜色。
渐变的过程就是: 在位置 0.0(起点)是 stop0
的颜色,然后颜色开始慢慢向 stop1
变化,直到到达位置 1.0(终点),完全变成 stop1
的颜色。
看到这里,是不是有点明白了
示例1
qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 red, /* 顶部红色 */stop:1 blue) /* 底部蓝色 */
1. 渐变方向:(x1:0, y1:0, x2:0, y2:1)
起点:(0, 0) - 这是渐变区域的左上角
终点:(0, 1) - 这是渐变区域的左下角
这两个点定义的向量 (x2-x1, y2-y1) 指明了渐变的方向。
这个方向向量是(0,1),所有渐变的方向是垂直向下(注意坐标系是左上角是原点)
2. 颜色设置:stop:0 red 和 stop:1 blue
停靠点 (stop) 系统:
- stop:0 = 在渐变路径的 起点(位置 0%)
- stop:1 = 在渐变路径的 终点(位置 100%)
具体颜色分配:
- stop:0 red:在渐变起点(顶部)使用红色
- stop:1 blue:在渐变终点(底部)使用蓝色
把这个方向和颜色结合起来,就得到了:
从上到下的红蓝渐变:
- 最顶部:纯红色
- 中间部分:红色逐渐与蓝色混合,产生紫色系过渡色
- 最底部:纯蓝色
示例2
qlineargradient(x1:0, y1:0, x2:1, y2:0,stop:0 red, /* 0%位置:红色 */stop:0.2 orange, /* 20%位置:橙色 */stop:0.4 yellow, /* 40%位置:黄色 */stop:0.6 green, /* 60%位置:绿色 */stop:0.8 blue, /* 80%位置:蓝色 */stop:1 purple) /* 100%位置:紫色 */
- 起点 (x1, y1) = (0,0)
- 终点 (x2, y2) = (1,0)
这两个点定义的向量 (x2-x1, y2-y1) 指明了渐变的方向。
这个方向向量是(1,0),所有渐变的方向是水平往右(注意坐标系是左上角是原点)
这意味着渐变方向是水平的,从左到右。
颜色停靠点(stop)有6个:
- 在从左往右0%位置(最左边)是红色
- 在从左往右20%位置是橙色
- 在从左往右40%位置是黄色
- 在从左往右60%位置是绿色
- 在从左往右80%位置是蓝色
- 在从左往右100%位置(最右边)是紫色
所以,这个渐变将从左到右经历:红色 -> 橙色 -> 黄色 -> 绿色 -> 蓝色 -> 紫色
具体来说,从0%到20%是红色到橙色的渐变,20%到40%是橙色到黄色的渐变,以此类推。
居然是彩虹色,我们需要来看看到底是什么效果
QWidget {background-color:qlineargradient(x1:0, y1:0, x2:1, y2:0,stop:0 red, /* 0%位置:红色 */stop:0.2 orange, /* 20%位置:橙色 */stop:0.4 yellow, /* 40%位置:黄色 */stop:0.6 green, /* 60%位置:绿色 */stop:0.8 blue, /* 80%位置:蓝色 */stop:1 purple); /* 100%位置:紫色 */
}
修改完之后,我们看看
7.6.给菜单设置样式
我们创建一个新的项目(基于QMainWindow类)
搞好之后,我们直接去这个.ui文件里面创建菜单和菜单项
/* 菜单栏样式 */
QMenuBar {/* 设置背景为从上到下的线性渐变,从浅灰到深灰 */background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 lightgray, stop:1 darkgray);/* 设置菜单项之间的间距为3像素 */spacing: 3px;
}/* 菜单栏中的项目样式 */
QMenuBar::item {/* 内边距:上下1像素,左右4像素 */padding: 1px 4px;/* 背景透明 */background: transparent;/* 圆角边框,半径为4像素 */border-radius: 4px;
}/* 菜单栏项目被选中时的样式(鼠标悬停或键盘选中) */
QMenuBar::item:selected {/* 背景色设置为中灰色 */background: #a8a8a8;
}/* 菜单栏项目被按下时的样式 */
QMenuBar::item:pressed {/* 背景色设置为深灰色 */background: #888888;
}/* 下拉菜单样式 */
QMenu {/* 背景色为白色 */background-color: white;/* 左右外边距各2像素,为菜单提供一些周围间距 */margin: 0 2px;
}/* 菜单项样式 */
QMenu::item {/* 内边距:上下2像素,右25像素,左20像素(为图标和选中标记预留空间) */padding: 2px 25px 2px 20px;/* 设置3像素透明边框,为选中状态时的边框预留空间 */border: 3px solid transparent;
}/* 菜单项被选中时的样式 */
QMenu::item:selected {/* 边框颜色设置为深蓝色 */border-color: darkblue;/* 背景色设置为半透明的深灰色 */background: rgba(100, 100, 100, 150);
}/* 菜单分隔线样式 */
QMenu::separator {/* 高度为2像素 */height: 2px;/* 背景色为浅蓝色 */background: lightblue;/* 左右外边距,使分隔线两侧有间距 */margin-left: 10px;margin-right: 5px;
}
我们直接运行
鼠标选中一个
下面是菜单项,菜单栏的常用QSS属性
1. QMenuBar::item
解释: 选中菜单栏中的所有元素(即每个顶级菜单项)。
作用对象: 应用程序顶部菜单栏上的每一个项目,比如“文件(F)”、“编辑(E)”、“视图(V)”等。
何时使用: 当你想要设置菜单栏中所有项目的通用样式时,比如默认的字体、颜色、内边距等。
示例: 如果你想将所有菜单栏项目的文字颜色设置为深蓝色,背景色设置为浅灰色,就会用到这个选择器。
2. QMenuBar::item:selected
解释: 选中菜单栏中的被鼠标悬停选中的元素。
作用对象: 菜单栏上当前鼠标正指向的那个项目。
何时使用: 当你想要改变用户用鼠标指向某个菜单项时的视觉效果,以提供高亮反馈。
示例: 当鼠标移到“文件”上时,“文件”二字背景变蓝,文字变白。这个样式就是由 QMenuBar::item:selected 控制的。
3. QMenuBar::item:pressed
解释: 选中菜单栏中的被鼠标点击的元素。
作用对象: 菜单栏上被鼠标按下(但还未释放)的那个项目。
何时使用: 当你想要模拟一个“按钮被按下”的视觉效果。
示例: 用户点击“文件”时,在鼠标按下的瞬间,让“文件”项目的背景色变得更深,以产生按下的感觉。
4. QMenu::item
解释: 选中下拉菜单中的所有元素。
作用对象: 点击顶级菜单后弹出的下拉菜单里的每一个项目。例如,点击“文件”后出现的“新建”、“打开”、“保存”等。
何时使用: 设置所有下拉菜单项的通用样式,如高度、字体、左边距等。
示例: 设置所有下拉菜单项的高度为25像素。
5. QMenu::item:selected
解释: 选中下拉菜单中的被鼠标悬停选中的元素。
作用对象: 下拉菜单中当前鼠标正指向的那个项目。
何时使用: 这是最常用的选择器之一,用于高亮显示用户即将点击的菜单项。
示例: 当鼠标在下拉菜单中移到“打开”上时,“打开”这一行背景变为蓝色。这个样式就是由 QMenu::item:selected 控制的。
6. QMenu::separator
解释: 选中菜单中的分割线。
作用对象: 用于对菜单项进行分组的那条灰色的横线。
何时使用: 当你想要自定义分割线的外观时,比如改变它的颜色、高度或左右边距。
示例: 将分割线的颜色从默认的灰色改为深灰色,并设置高度为2像素。
7.7.给窗口设置背景图
让窗口变好看,一个最直接的办法就是设置背景图片。
不过你可能也发现了,在 Qt 里面,如果你直接给顶层的 QWidget 设置背景图,经常会没有效果——具体为啥暂时不太清楚,可能是 Qt 本身的设计机制导致的。
那怎么办呢?
一个常用的办法是:在外面再包一层和窗口一样大小的 QFrame(QFrame 也是 QWidget 的一种),然后对这个 QFrame 设置背景。
结构上大概是这样的:
QWidget(顶层窗口)
└── QFrame(和窗口一样大)└── QVBoxLayout├── QCheckBox├── QLineEdit├── QLineEdit└── QPushButton
接下来就是设置背景图的问题了。
除了常见的 background-image
属性之外,Qt 还提供了 border-image
这个属性。
用 border-image
的好处是,图片会自动跟着控件的大小拉伸,不会出现固定大小不适应窗口变化的问题。
所以如果你希望背景能自适应窗口,推荐试试 border-image
~
话不多说,我们直接看例子
我们把背景图设置成下面这个
首先我们先创建qrc文件
这个如果我们直接进去.ui文件
然后写一下下面这个
QWidget {background-image: url(:/picture.png);
}
点击OK,我们却发现没有什么变化
然后我一点击运行,发现居然是下面这个效果
这就是不对的了,为了能正常显示,我们需要在QWidget的基础之上再套一个QFrame。
QFrame就是QWidget的子类。
我们把它放大到和QWidget一样大
这个时候
QFrame {background-image: url(:/picture.png);
}
一点击OK,他就里面渲染出来了。
运行一下
这个和我们原来的图差的有的多啊
1. background-image:像贴“墙纸”
行为:你把一张图片(墙纸)贴在控件(墙面)上。这张图片有它自己固定的大小。
特点:
- 默认不拉伸:如果你这张“墙纸”比“墙面”小,它会默认从左上角开始贴,然后不断重复(平铺),直到铺满整个区域。这通常不是你想要的窗口背景效果。
- 可以控制位置和重复方式:你可以通过其他CSS属性来精细控制,比如 background-repeat: no-repeat;(不让它重复),然后 background-position: center;(让它居中)。但即使这样,如果控件变大了,图片本身还是原来那么大,周围会留出空白。
简单来说:background-image 更像是一个“图案”,它不一定能完美适应控件尺寸的变化。
2. border-image:像用“可拉伸的橡胶画”
行为:它把你的图片当成一张“橡胶画”,通过一个叫“九宫格”的聪明方法,把图片分成9个部分,然后根据控件的大小进行智能拉伸。
特点:
- 自动拉伸填充:它会自动把图片拉伸(或缩放)到和控件一模一样的大小,完美填充,不会有留白或重复。
- 专为适应大小而生:这正是你想为整个窗口设置背景时最需要的特性!无论用户怎么拖拽窗口改变大小,背景图都会立刻适应。
简单来说:border-image 是一个“自适应背景”,它能保证图片始终填满整个控件。
说到这里,我们赶紧去修改一下
QFrame {border-image: url(:/picture.png);
}
我们一点击OK,就变成下面这样子了
我们运行一下
很完美啊!!