【Qt】界面优化

🌈个人主页: 秦jh__https://blog.csdn.net/qinjh_?spm=1010.2135.3001.5343
🔥 系列专栏: https://blog.csdn.net/qinjh_/category_13030435.html

目录

QSS

背景介绍

基本语法

QSS设置⽅式

指定控件样式设置

全局样式设置

从⽂件加载样式表

使⽤QtDesigner编辑样式

选择器

选择器概况

⼦控件选择器(Sub-Controls)

伪类选择器(Pseudo-States)

样式属性

盒模型(BoxModel)

控件样式⽰例

按钮

复选框

单选框

输⼊框

列表

菜单栏

登录界⾯

⼩结

绘图

基本概念

绘制各种形状

绘制⽂本

设置画笔

设置画刷

绘制图⽚

绘制简单图⽚

平移,旋转图⽚

特殊的绘图设备

QPixmap

QImage

QPicture


前言

💬 hello! 各位铁子们大家好哇。

今日更新了Qt界面优化的内容

🎉 欢迎大家关注🔍点赞👍收藏⭐️留言📝

QSS

背景介绍

在⽹⻚前端开发领域中,CSS是⼀个⾄关重要的部分.描述了⼀个⽹⻚的"样式".从⽽起到对⽹⻚美化的 作⽤.

所 谓样式,包括不限于⼤⼩,位置,颜⾊,背景,间距,字体等等.

Qt 仿照CSS的模式,引⼊了QSS,来对Qt中的控件做出样式上的设定,从⽽允许程序猿写出界⾯更好看 的代码.

同样受到HTML的影响,Qt还引⼊了QML来描述界⾯,甚⾄还可以直接把⼀个原⽣的html⻚⾯加载 到界⾯上

当然,由于Qt本⾝的设计理念和⽹⻚前端还是存在⼀定差异的,因此QSS中只能⽀持部分CSS属性. 整体来说QSS要⽐CSS更简单⼀些

注意:

如果通过QSS设置的样式和通过C++代码设置的样式冲突,则QSS优先级更⾼

基本语法

对于CSS来说,基本的语法结构⾮常简单

QSS沿⽤了这样的设定

其中:

  • 选择器描述了"哪个widget要应⽤样式规则".
  • 属性则是⼀个键值对,属性名表⽰要设置哪种样式,属性值表⽰了设置的样式的值.

例如:

上述代码的含义表⽰,针对界⾯上所有的QPushButton,都把⽂本颜⾊设置为 红⾊

编 写QSS时使⽤单⾏的格式和多⾏的格式均可.

代码⽰例:

在界⾯上创建⼀个按钮.

代码:

运⾏程序,观察效果.可以看到⽂本已经是红⾊了

注意:上述代码中,我们是只针对这⼀个按钮通过 setStyleSheet ⽅法设置的样式.此时这个样式 仅针对该按钮⽣效.如果创建其他按钮,其他按钮不会受到影响

QSS设置⽅式

指定控件样式设置

QWidget 中包含了 setStyleSheet ⽅法,可以直接设置样式.

另⼀⽅⾯,给指定控件设置样式之后,该控件的⼦元素也会受到影响.

代码⽰例:⼦元素受到影响

修改widget.cpp,这次我们不再给按钮设置样式,⽽是给Widget设置样式(Widget是 QPushButton的⽗控件).

运⾏程序,可以看到样式对于⼦控件按钮同样会⽣效.

全局样式设置

还可以通过 QApplication 的 setStyleSheet ⽅法设置整个程序的全局样式.

全局样式优点:

  • 使同⼀个样式针对多个控件⽣效,代码更简洁.
  • 所有控件样式内聚在⼀起,便于维护和问题排查.

代码⽰例:使⽤全局样式

在界⾯上创建三个按钮.

编辑main.cpp,设置全局样式

运⾏程序,可以看到此时三个按钮的颜⾊都设置为红⾊了.

这里有两个问题:

  1. 如果设置了全局样式,然后在某个控件里又设置了其他的样式,会咋样?
  2. 如果设置了全局样式,在某个控件里设置的样式和全局样式冲突了,又会咋样?

继续使用上一个例子的代码,修改widget.cpp

运行结果:

第⼀个按钮,同时具备了颜⾊和字体⼤⼩样式。说明针对第⼀个按钮,两种设置⽅式设置的样式,叠加起来了

形如上述这种属性叠加的效果,我们称为"层叠性".

第二个按钮变成了绿色,在CSS中也存在类似的优先级规则.通常来说都是"局部"优先级⾼于"全局"优先级. 相当于全局样式先"奠定基调",再通过指定控件样式来"特事特办"

从⽂件加载样式表

上述代码都是把样式通过硬编码的⽅式设置的.这样使QSS代码和C++代码耦合在⼀起了,并不⽅便代 码的维护

因此更好的做法是把样式放到单独的⽂件中,然后通过读取⽂件的⽅式来加载样式

代码⽰例:从⽂件加载全局样式

在界⾯上创建⼀个按钮

创建 resource.qrc ⽂件,并设定前缀为 /

创建 style.qss ⽂件,并添加到 resource.qrc 中.

style.qss 是需要程序运⾏时加载的.为了规避绝对路径的问题,仍然使⽤ qrc的方式组织.(即把资源⽂件内容打包到cpp代码中).

QtCreator没有提供创建 qrc 的⽅式来组 qss ⽂件的选项.咱们直接右键->新建⽂件->⼿动设置⽂件扩展名为qss即可.

使⽤QtCreator打开 style.qss ,编写内容

修改main.cpp

运⾏程序,可以看到样式已经⽣效了

使⽤QtDesigner编辑样式

QSS也可以通过QtDesigner直接编辑,从⽽起到实时预览的效果.同时也能避免C++和QSS代码的耦 合.

代码⽰例:使⽤QtDesigner编辑样式

在界⾯上创建⼀个按钮

右键按钮,选择"改变样式表"

在弹出的样式表编辑器中,可以直接填写样式.填写完毕,点击OK即可

此时QtDesigner的预览界⾯就会实时显⽰出样式的变化

这种⽅式设置样式,样式内容会被以xml格式记录到ui⽂件中

当我们发现⼀个控件的样式不符合预期的时候,要记得排查这四个地⽅:

  • 全局样式
  • 指定控件样式
  • qss⽂件中的样式
  • ui⽂件中的样式

选择器

选择器概况

QSS的选择器⽀持以下⼏种:

总体来说,QSS选择器的规则和CSS选择器基本⼀致

只熟悉最常⽤的⼏个即可(上述加粗的)

代码⽰例:使⽤类型选择器选中⼦类控件

代码:

运行结果:

当某个控件⾝上,通过类型选择器和ID选择器设置了冲突的样式时,ID选择器样式优先级更 ⾼

实践中我们可以简单的认为,选择器描述的范围越精准,则优先级越⾼.⼀般来说,ID选择器优 先级是最⾼的

代码⽰例:使⽤并集选择器

编写main.cpp,设置全局样式

运行结果:

并集选择器是⼀种很好的代码复⽤的⽅式.很多时候我们希望界⾯上的多个元素⻛格是统⼀ 的,就可以使⽤并集选择器,把样式属性同时指定给多种控件

⼦控件选择器(Sub-Controls)

有些控件内部包含了多个"⼦控件".⽐如QComboBox的下拉后的⾯板,⽐如QSpinBox的上下按钮 等

可以通过⼦控件选择器 :: ,针对上述⼦控件进⾏样式设置

代码⽰例:设置下拉框的下拉按钮样式

在界⾯上创建⼀个下拉框,并创建⼏个选项

创建 resource.qrc ,并导⼊图⽚

修改main.cpp

  • 使⽤⼦控件选择器 QComboBox::down-arrow 选中了QComboBox 的下拉按钮
  • 再通过 image 属性设置图⽚.

执⾏程序,观察效果

伪类选择器(Pseudo-States)

伪类选择器,是根据控件所处的某个状态被选择的.例如按钮被按下,输⼊框获取到焦点,⿏标移动到某 个控件上等

  • 当状态具备时,控件被选中,样式⽣效.
  • 当状态不具备时,控件不被选中,样式失效

使⽤ : 的⽅式定义伪类选择器.

常⽤的伪类选择器

这些状态可以使⽤ ! 来取反.⽐如 :!hover 就是⿏标离开控件时, :!pressed 就是⿏标松开时, 等等.

代码⽰例:设置按钮的伪类样式.

在界⾯上创建⼀个按钮

编写main.cpp,创建全局样式

运⾏程序,可以看到,默认情况下按钮⽂字是红⾊,⿏标移动上去是绿⾊,⿏标按下按钮是蓝⾊

样式属性

QSS中的样式属性⾮常多,不需要都记住.核⼼原则还是⽤到了就去查. ⼤部分的属性和CSS是⾮常相似的.

⽂档的 Qt Style Sheets Reference 章节详细介绍了哪些控件可以设置属性,每个控 件都能设置哪些属性等.

在翻阅⽂档的时候涉及到⼀个关键术语"盒模型"(BoxModel).这⾥我们需要介绍⼀下

盒模型(BoxModel)

⼀个遵守盒模型的控件,由上述⼏个部分构成

  • Content矩形区域:存放控件内容.⽐如包含的⽂本/图标等.
  • Border矩形区域:控件的边框.
  • Padding矩形区域:内边距.边框和内容之间的距离.
  • Margin矩形区域:外边距.边框到控件 geometry 返回的矩形边界的距离

默认情况下,外边距,内边距,边框宽度都是0.

可以通过⼀些QSS属性来设置上述的边距和边框的样式.

代码⽰例:设置边框和内边距

在界⾯上创建⼀个label

修改main.cpp,设置全局样式

  • border:20px dashed green 相当于 border-style: dashed; border-width: 20px ; border-color: green ; 三个属性的简写形式
  • padding-left:50px; 是给左侧设置内边距.

运⾏程序,可以看到样式发⽣了变化

代码⽰例:设置外边距

创建一个按钮

效果如下图:

设置样式.

运⾏程序,可以看到,当前按钮的边框被外边距挤的缩⼩了.但是获取到的按钮的Geometry是不变的

控件样式⽰例

按钮

代码⽰例:⾃定义按钮

右键->改变样式表,使⽤QtDesigner设置样式

形如 #dadbde 是计算机中通过⼗六进制表⽰颜⾊的⽅式.

执⾏程序,可以看到效果

属性⼩结

复选框

代码⽰例:⾃定义复选框

创建⼀个 resource.qrc ⽂件,并导⼊以下图⽚

使⽤⿊⾊作为默认形态. 使⽤蓝⾊作为hover形态. 使⽤红⾊作为pressed形态.

创建⼀个复选框

编辑复选框的样式

运⾏程序,可以看到此时的复选框就变的丰富起来了

⼩结:

单选框

输⼊框

代码⽰例:⾃定义单⾏编辑框

在QtDesigner中编写样式

执⾏程序观察效果.

小结

列表

代码⽰例:⾃定义列表框

在界⾯上创建⼀个ListView

编写代码

执⾏程序,观察效果

关于 qlineargradient

qlineargradient 有6个参数.

x1, y1: 标注了⼀个起点.

x2, y2: 标注了⼀个终点.

这两个点描述了⼀个"⽅向".

例如:

  • x1:0,y1:0,x2:0, y2: 1 就是垂直⽅向从上向下进⾏颜⾊渐变.
  • x1:0,y1:0,x2:1, y2: 0 就是⽔平⽅向从左向右进⾏颜⾊渐变.
  • x1:0,y1:0,x2:1, y2: 1 就是从左上往右下⽅向进⾏颜⾊渐变

stop0 和stop1描述了两个颜⾊.渐变过程就是从stop0往stop1进⾏渐变的.

菜单栏

代码⽰例:⾃定义菜单栏

创建菜单栏

编写样式

执⾏程序,观察效果

登录界⾯

  1. 在界⾯上创建元素。使⽤布局管理器,把上述元素包裹⼀下.
  • 使⽤ QVBoxLayout 来管理上述控件.
  • 两个输⼊框和按钮的minimumHeight均设置为50.(元素在布局管理器中⽆法直接设置width和 height, 使⽤minimumWidth和minimumHeight代替,此时垂直⽅向的sizePolicy要设为fixed).
  • 右键 QCheckBox ,选择 Layout Alignment 可以设置checkbox的对⻬⽅式(左对⻬,居中对 ⻬,右对⻬).

设置背景图⽚

把上述控件添加⼀个⽗元素QFrame,并设置QFrame和窗⼝⼀样⼤

把其他控件都放到QFrame里面,然后把QFrame拖到最大。

顶层窗⼝的QWidget⽆法设置背景图⽚.因此我们需要再套上⼀层QFrame.背景图⽚就设置 到QFrame上即可

创建resource.qrc, 并导⼊图⽚

样式代码

使⽤ border-image 设置背景图⽚,⽽不是 background-image .主要是因为 border-image 是可以⾃动缩放的.这⼀点在窗⼝⼤⼩发⽣改变时是⾮常有意义的.

背景⾊使⽤ transparent 表⽰完全透明(应⽤⽗元素的背景)

执⾏程序

⼩结

QSS本⾝给Qt提供了更丰富的样式设置的能⼒,但是整体来说QSS的功能是不如CSS的.

在CSS中,整个⽹⻚的样式,都是CSS⼀⼿负责,CSS功能更强⼤,并且也更可控.

相⽐之下,Qt中是以原⽣api为主,来控制控件之间的尺⼨,位置等,QSS只是起到辅助的作⽤.

⽽且Qt中提供的⼀些"组合控件"(像QComboBox,QSpinBox等)内部的结构是不透明的,此时进⾏⼀ 些样式设置也会存在⼀定的局限性.

绘图

基本概念

虽然Qt已经内置了很多的控件,但是不能保证现有控件就可以应对所有场景.

很多时候我们需要更强的"⾃定制"能⼒.

Qt 提供了画图相关的API,可以允许我们在窗⼝上绘制任意的图形形状,来完成更复杂的界⾯设计

所谓的"控件",本质上也是通过画图的⽅式画上去的.

画图API和控件之间的关系,可以类⽐成机器指令和⾼级语⾔之间的关系.

控件是对画图API的进⼀步封装;画图API是控件的底层实现

绘图API核⼼类

绘图API的使⽤,⼀般不会在QWidget的构造函数中使⽤,⽽是要放到paintEvent事件中

关于 paintEvent paintEvent 会在以下情况下被触发:

  • 控件⾸次创建.
  • 控件被遮挡,再解除遮挡.
  • 窗⼝最⼩化,再恢复.
  • 控件⼤⼩发⽣变化时.
  • 主动调⽤ repaint() 或者 update() ⽅法.(这两个⽅法都是 QWidget 的⽅法).
  • ......

因此,如果把绘图api放到构造函数中调⽤,那么⼀旦出现上述的情况,界⾯的绘制效果就⽆法确保符合 预期了

绘制各种形状

在"widget.h"头⽂件中声明绘图事件;

在"widget.cpp"⽂件中重写paintEvent()⽅法;

实现效果如下:

绘制⽂本

QPainter类中不仅提供了绘制图形的功能,还可以使⽤QPainter::drawText()函数来绘制⽂字,也可 以使⽤QPainter::setFont() 设置字体等信息。

⽰例:

运行结果:

注意理解这里坐标的位置:

此处的0 横坐标,表示的是文字最左侧的位置。

此处的100 纵坐标,表示的是文字的"基线位置"。

设置画笔

QPainter 在绘制时,是有⼀个默认的画笔的。在使⽤时也可以⾃定义画笔。在Qt中,QPen类中定义 了QPainter应该如何绘制形状、线条和轮廓。同时通过QPen类可以设置画笔的线宽、颜⾊、样式、 画刷等。

画笔的颜⾊可以在实例化画笔对象时进⾏设置,画笔的宽度是通过setWidth()⽅法进⾏设置,画笔的 ⻛格是通过setStyle()⽅法进⾏设置,设置画刷主要是通过setBrush()⽅法。

  • 设置画笔颜⾊:QPen::QPen(const QColor &color) 画笔的颜⾊主要是通过QColor类设置;
  • 设置画笔宽度:void QPen::setWidth(int width)
  • 设置画笔⻛格:void QPen::setStyle(Qt::PenStyle style)

画笔的⻛格有:

⽰例:画笔的使⽤

实现效果如下:

设置画刷

在Qt中,画刷是使⽤QBrush类来描述,画刷⼤多⽤于填充。QBrush定义了QPainter的填充模式, 具有样式、颜⾊、渐变以及纹理等属性。

画刷的格式中定义了填充的样式,使⽤Qt::BrushStyle枚举,默认值是Qt::NoBrush,也就是不进⾏ 任何填充。可以通过Qt助⼿查找画刷的格式。如下图⽰:

设置画刷主要通过void QPen::setBrush(const QBrush &brush)⽅法,其参数为画刷的格式。

⽰例:

实现效果:

绘制图⽚

Qt 提供了四个类来处理图像数据:QImage、QPixmap、QBitmap和QPicture,它们都是常⽤的绘 图设备。其中QImage主要⽤来进⾏I/O处理,它对I/O处理操作进⾏了优化,⽽且可以⽤来直接访问 和操作像素;QPixmap主要⽤来在屏幕上显⽰图像,它对在屏幕上显⽰图像进⾏了优化;QBitmap 是QPixmap的⼦类,⽤来处理颜⾊深度为1的图像,即只能显⽰⿊⽩两种颜⾊;QPicture⽤来记录并 重演QPainter命令。这里只讲QPixmap。

绘制简单图⽚

在"widget.h"头⽂件中声明绘画事 件;如下图⽰:

将资源⽂件添加⾄项⽬中;

在"widget.cpp"⽂件中实现画图⽚功能;

运行结果:

图片的左上角从坐标(100,100)开始

还可以进行缩放

平移,旋转图⽚

平移图⽚实际是通过改变坐标来实现。QPainter类中提供了translate()函数来实现坐标原点的改变。

图⽚的旋转使⽤的是QPainter类中的rotate()函数,它默认是以原点为中⼼进⾏旋转的。如果要改变 旋转的中⼼,可以使⽤translate()函数完成。

这里旋转后,看不到图片,需要进行平移。

运行结果:

特殊的绘图设备

前⾯的代码中我们是使⽤QWidget作为绘图设备.在Qt中还存在下列三个⽐较特殊的绘图设备.此处 我们也简要介绍.

  • QPixmap⽤于在显⽰器上显⽰图⽚.
  • QImage⽤于对图⽚进⾏像素级修改.
  • QPicture⽤于对QPainter的⼀系列操作进⾏存档

QPixmap

QPixmap核⼼特性:

  • 使⽤QPainter直接在上⾯进⾏绘制图形.
  • 通过⽂件路径加载并显⽰图⽚.
  • 搭配QPainter的drawPixmap()函数,可以把这个图⽚绘制到⼀个QLabel、QPushButton等控件 上.
  • 和系统/显⽰设备强相关,不同系统/显⽰设备下,QPixmap的显⽰可能会有所差别.

QImage

QImage的核⼼特性:

  • 使⽤QPainter直接在上⾯进⾏绘制图形.
  • 通过⽂件路径加载并显⽰图⽚.
  • 能够针对图⽚进⾏像素级别的操作(操作某个指定的像素).
  • 独⽴于硬件的绘制系统,能够在不同系统之上提供⼀致的显⽰.

QPicture

QPicture 核⼼特性:

  • 使⽤QPainter直接在上⾯进⾏绘制图形.
  • 通过⽂件路径加载并显⽰图⽚.
  • 能够记录QPainter的操作步骤.
  • 独⽴于硬件的绘制系统,能够在不同系统之上提供⼀致的显⽰.

注意: QPicture 加载的必须是⾃⾝的存档⽂件,⽽不能是任意的png,jpg等图⽚⽂件.

相关推荐
阿蒙Amon2 小时前
C#每日面试题-简述泛型约束
java·开发语言·c#
zh_xuan2 小时前
kotlin 延迟属性
开发语言·kotlin
进击的小头2 小时前
创建型模式:简单工厂模式(C语言实现)
c语言·开发语言·简单工厂模式
2501_944424122 小时前
Flutter for OpenHarmony游戏集合App实战之记忆翻牌表情图案
开发语言·javascript·flutter·游戏·harmonyos
爱吃大芒果2 小时前
Flutter for OpenHarmony前置知识:Dart 语法核心知识点总结(上)
开发语言·flutter·dart
2501_944424122 小时前
Flutter for OpenHarmony游戏集合App实战之数字拼图打乱排列
android·开发语言·flutter·游戏·harmonyos
运维行者_2 小时前
OpManager 对接 ERP 避坑指南,网络自动化提升数据同步效率
运维·服务器·开发语言·网络·microsoft·网络安全·php
爱编程的小庄2 小时前
Rust初识
开发语言·rust
23124_802 小时前
热身签到-ctfshow
开发语言·python