Qt:界面优化
目录
QSS的使用
设置全局样式
样式和代码分离
选择器的用法
盒子模型
给按钮设置样式
给复选框设置样式
给输入框设置样式
给列表框设置样式
给菜单栏设置样式
实现登录界面
Qt 中对于界面优化,采用的是 QSS,QSS 其实是参考的网页前端的 CSS,从名称就能看出来
QSS 能够针对界面的"样式"来进行设置
包括不限于: 大小, 位置, 颜色, 背景, 间距, 字体.….
CSS 的功能是非常强大,非常丰富的
QSS 要逊色一些,但也能完成很多的工作
有时候, 可以通过 QSS 设置样式 (设置字体属性)
也可以通过 C++ 代码设置样式
如果两者冲突,QSS 优先级更高
QSS的使用
语法结构:
选择器{
属性名: 属性值;
......
}
- 选择器: 先选择某个/某一类控件, 接下来进行的各种属性设置,都是针对选中的控件生效的
- 键值对: 针对某些样式具体的设置了
例如:
QPushButton {
color: red;
}
上述代码的含义表示,针对界面上所有的 OPushButton,都把文本颜色设置为 红色
下面图形化界面的方式创建一个按钮:
构造函数中修改颜色:
运行程序,按钮就变为红色了:
如果有两个按钮,此时也只会对第一个按钮生效, 因为程序中针对的是 ui->pushButton,而没有针对 pushButton_2
设置样式的时候,是可以指定某个控件来设置的
指定控件之后,此时的样式就会针对这个指定的控件,也会针对子控件生效
如果我们代码改为 this,也就是整个 Widget:
此时也会对 Widget 下面的子控件生效,也就是所有 QPushButton 都会生效:
设置全局样式
也就是将界面上所有的样式都集中到一起来组织
全局样式的设置是需要在 main.cpp 中编写的,核心是通过 QApplication 的对象来进行设置
此时我们创建的三个按钮就全部是红色了:
1.如果设置了全局样式,然后在某个控件里又设置了其他的样式,会咋样?
上面已经给全局样式设置了颜色为红色,全局样式并没有设置字体大小相关属性,这里我们给第一个按钮设置字体大小:
效果如下:
从上面的样例可以看出,此时这两方面的样式,会"叠加"起来,叫做 层叠性
2.如果设置了全局样式,在某个控件里设置的样式和全局样式冲突了,又会咋样?
下面局部设置按钮2的颜色为绿色:
效果为:
所以得到结论:
当全局样式和局部样式冲突的时候,局部样式的优先级是更高的,覆盖了对应的全局样式
- 实际开发中,就可以在全局样式中设置比较通用的样式,统一整个程序的界面风格
- 如果需要针对某个控件进行微调,可以使用局部样式来做出调整
样式和代码分离
QSS 上述代码中,样式代码和 C++ 代码都是混在一起的
- 如果 QSS 样式代码比较简单,那是没什么问题的
- 如果 QSS 代码非常复杂,继续这样搞,代码的维护成本就很高了
所以我们就可以把样式代码拎出来,放到单独的文件中,后续可以直接让 C++ 代码来读取并加载文件内容
首先创建一个按钮:
下面进行三个步骤:
1.创建 qrc 文件, 通过 qrc 管理样式文件
2.创建单独的 qss 文件,把这样的文件放到 qrc 中
3.编写 C++ 代码, 读取 qss 文件中的内容,并设置样式
在对应文件夹中右键创建 style.qss
选择 style.qss,此时就通过 qrc 管理样式文件了:
接着点击文件-打开,打开刚刚创建的 .qss 文件,添加下面内容:
接着在 main.cpp 中,新创建一个函数去读取 qss 文件中的内容:
此时按钮就按照 qss 文件内容改变样式了:
这个方案仅供大家参考,实际开发中还有更方便的方案
Qt Designer 中直接集成这样的功能,允许我们把样式直接写到 .ui 文件里
同样先创建一个按钮:
选中整个页面,右键,点击 改变样式表:
通过这里就可以编写界面的样式了,这里进行的修改都会记录到 ui 文件中,并且在程序运行时自动生效,而且这里还能进行预览
此时点击确定,就直接能预览修改后的效果:
由于设置样式太灵活,有很多地方都能设置,就导致当某个控件样式不符合预期的时候,排查起来就比较麻烦了
所以排查时需要注意的地方很多:
- 全局样式(QApplication 设置的)
- 指定控件的样式 (这个控件是否设置了样式)
- 指定控件的父控件的样式(可能是从父控件继承过来的)
- qss 文件中的样式
- ui 文件中的样式
所以实际开发中,如果需要设置样式,建议最好统一使用某一种方式来设置
选择器的用法
QSS 的选择器支持下面几种,其中加粗的是用的比较多的:
类型选择器
先创建一个按钮:
在 main.cpp 中编写下面的代码:
此时按钮就会变为红色
上述的代码,前面的 QPushButton 其实就是类型选择器了(QWidget 也会变红,因为对子控件也会产生影响)
类选择器
但是如果使用类选择器,也就是前面加上点,此时就不会对子类生效了:
效果为:
id选择器
在开发中,期望不同的按钮控件样式不同,此时就需要使用 id选择器 了
在 main.cpp 中添加下面的代码,前面加 # 表示 id选择器:
此时运行程序,效果为:
上述代码中,通过类型选择器其实也把第二、三个按钮选中了,但是后面又通过 id选择器 选中了,所以我们认为:
此时当类型选择器和 id 选择器选中同一个控件的时候,并且设置的样式是冲突的,此时 id 选择器的优先级更高
如果不冲突,那就会同时生效
并集选择器
并集选择器可以同时选中多个控件
下面在添加一个 Label 和一个 line edit:
再在 main.cpp 中添加样式表:
此时运行程序:
注意:上述使用并集选择器时,不光可以选择类型,也可以写成id:
子控件选择器
有些控件是比较复杂的,所以控件里面也会包含其他的控件
例如:
前面学习的 QSpinBox,后面还会有两个微调按钮,点击就会发送改变,像这种控件,我们就认为整个 QSpinBox 是一个总的控件,里面的两个按钮就是子控件
还有 QComboBox,整个 QComboBox 就是一个总控件,下拉框和下拉按钮就是子控件
如果想要了解 Qt 中哪些控件是有子控件的,就需要去查阅文档了:
直接搜索 Qt Style Sheets Reference
点击最下面的 List of Sub-Controls:
点击后,就能看出来每一个子控件是从属于哪些控件的:
下面我们给 QComboBox 的下拉按钮添加一个图标,这时就需要采用子控件选择器了
初始下拉框样式如下:
同样是通过 qrc机制 管理图片:
在 main.cpp 中新增代码:
效果为:
伪类选择器
伪类选择器,是根据控件所处的某个状态被选择的,例如按钮被按下,输入框获取到焦点,鼠标移动到某个控件上等
- 当状态具备时,控件被选中,样式生效.
- 当状态不具备时,控件不被选中,样式失效
使用 : 的方式定义伪类选择器
常用的伪类选择器:
这些状态可以使用 !来取反,比如 :!hover 就是鼠标离开控件时,:!pressed 就是鼠标松开时
同样也可以在文档中查看,最后一个是子选择器,倒数第二个就是伪类选择器
下面在 main.cpp 中演示 伪类选择器 的用法:
此时就能够做到,按钮为红色,鼠标放在按钮上变为绿色,鼠标按下按钮,变为蓝色
当然了,上述的功能,也可以通过事件的方式来实现,自己创建一个类继承自 QPushButton,再重写几个事件即可
盒子模型
box model:叫做盒子模型,也是来自于 CSS
- margin:外边距
- border:边框
- padding:内边距
- content:内容
可以通过一些 QSS 属性来设置上述的边距和边框的样式:
复合属性,指的是可以拆成4个属性,以 margin 为例,可以拆分为:
margin-left、margin-right、margin-top、margin-bottom
在使用时(CSS也是这样设定的):
margin:10px;四个方向都是 10px 的外边距
margin: 10px 20px;上下是 10px,左右是 20px.
margin: 10px 20px 30px 40px;上右下左分别设定(顺时针)
下面演示具体的使用
首先创建一个 Label:
在 main.cpp 中设置全局样式:
效果为(padding改变的是文字和边框的距离):
下面演示改变外边框:
先不设置外边距:
效果为:
设置外边距:
此时效果为(margin改变的是边框距离整个窗口左上角的距离):
可以看到,再给按钮设置完外边距后,按钮大小缩小了,如果打印此时按钮的大小:
发现尺寸还是 100*100:
所以在指定外边距后,会让我们看起来的效果变小了,但是实际上占据的空间还是这么大
给按钮设置样式
首先创建一个按钮:
右键按钮,编辑样式表:
效果为:
- font-size 设置字体大小
- border-radius 设置圆角矩形
- background-color 设置背景色
- color 设置文字颜色
给复选框设置样式
接下来给复选框设置样式,我们提前下载好三种方框,以及三种方框勾选后的图片,如下所示:
- 使用黑色作为默认形态
- 使用蓝色作为 hover 形态
- 使用红色作为 pressed 形态
首先创建 checkBox 复选框:
接着使用 qrc机制 导入这几张图片:
下面右键复选框,改变样式表,先将文字和框的大小变大些:
效果为:
下面需要使用子控件选择器,选择 checkBox 前面的 小框:
填写在 url 后面的括号时,可以点击上面的添加资源,比较方便:
下面改变为:
默认是黑框,鼠标放上去是蓝框,点下去是红框
总结一下:
给输入框设置样式
首先创建一个 line edit:
右键输入框,点击改变样式表:
此时效果为:
下面是一些属性说明:
给列表框设置样式
先创建一个 List Widget,并添加几个选项:
右键改变样式表:
效果为:
上述设置的是纯色的, 还可以设置渐变色,使用属性 qlineargradient 设置渐变色(线性渐变),此处需要填写六个参数:
坐标是非0即1的,也就是最小是0,最大是1
- x1: 起点的横坐标
- y1: 起点的纵坐标
- x2: 终点的横坐标
- y2: 终点的纵坐标
- stop: 0 起始颜色
- stop: 1 结束颜色
例如:
x1:0,y1: 0,x2: 1,y2: 0,就是从左到右的渐变
x1:0,y1: 0,x2: 0,y2: 1,就是从上到下的渐变
x1:0,y1: 0,x2: 1,y2: 1,就是从左上到右下的渐变,对角线方向
下面就改变样式表,改为渐变色:
效果为:
给菜单栏设置样式
首先创建一个菜单,下面有几个菜单项:
针对整个窗口右键,改变样式表:
- spacing:菜单之间的间隔
- QMenu::item 是为了选中某个菜单项时,字体不会变动(因为选择某个菜单项时会加上边框,与不加边框的字显示不桶了)
效果为:
一些要点:
实现登录界面
在我们的日常生活中,登录界面可以说是随处可见了,下面就使用 Qt 实现一个登录界面,并使用 QSS 对它进行样式的设置
图形化界面的方式创建:
因为将这几个控件放入布局管理器中了,所以不能设置大小了,但是我们可以通过设置最小高度、最大高度,来达到我们想要的高度
接着我们想将这个登录界面设置的好看些,所以可以设置一下登录界面的背景图片,使用 qrc 导入图片
直观想法,是直接给 QWidget 顶层窗口设置背景图
但是 Qt 中存在限制,直接给顶层窗口设置背景会失效
所以解决方式就是:
可以给上述控件外头套上一个和窗口一样大小的 QFrame 控件
此时的关系如下所示,先是 QWidget,QWidget 里面有一个 QFrame,QFrame 里面才是这几个控件
下面鼠标点击上图的 QWidget,右键点击改变样式表:
Qt 中设置背景图,除了 background-image 之外,还有 border-image 属性
- background-image:背景图片固定大小
- border-image:通过这种方式设置的背景,会自动跟随控件的大小变化(推荐)
效果为:
接着继续设置其他样式:
此时效果如下:
Qt:界面优化到此结束