目录

接下来的日子会顺顺利利,万事胜意,生活明朗-----------林辞忧
前言
Qt 仿照CSS的模式,引⼊了QSS,来对Qt中的控件做出样式上的设定,从⽽允许程序猿写出界⾯更好看 的代码.当然,由于Qt本⾝的设计理念和⽹⻚前端还是存在⼀定差异的,因此QSS中只能⽀持部分CSS属性. 整体来说QSS要⽐CSS更简单⼀些.
如果通过QSS设置的样式和通过C++代码设置的样式冲突,则QSS优先级更⾼
QSS基础知识
1.基本语法
选择器 { 属性名 : 属性值 ; }
选择器:先选择某一个/某一类控件,接下来进行的各种属性设置,都是针对选中的控件生效的
• 属性则是⼀个键值对,属性名表⽰要设置哪种样式,属性值表⽰了设置的样式的值
例如:

上述代码的含义表⽰,针对界⾯上所有的QPushButton,都把⽂本颜⾊设置为红色
2.代码实例:QSS基本使⽤
在设置样式的时候,可以指定某个控件来设置;也可以指定控件设置,此时的样式就会针对这个指定的控件,也会针对子控件生效

这里的QPushButton是没有子控件的

这里会针对this的子控件也生效
3.全局样式设置
还可以通过 QApplication 的 setStyleSheet ⽅法设置整个程序的全局样式.
全局样式优点:
• 使同⼀个样式针对多个控件⽣效,代码更简洁.
• 所有控件样式内聚在⼀起,便于维护和问题排查.
代码实例:使⽤全局样式

当设置了全局样式,然后在某个控件里又设置了其它的样式,会咋样的?

会发现这两方面的样式就会叠加的。形如上述这种属性叠加的效果,我们称为"层叠性"
如果设置了全局样式,在某个控件里设置的样式和全局样式冲突了,会咋样?
当全局样式和局部样式冲突时,局部样式的优先级是更高的,覆盖了对应的全局样式。在实际开发中,就可以在全局样式中设置比较通用的样式,统一整个程序的界面风格,如果需要针对某个控件进行微调,可以使用局部样式作出调整
4.从⽂件加载样式表
上述代码都是把样式通过硬编码的⽅式设置的.这样使QSS代码和C++代码耦合在⼀起了,并不⽅便代 码的维护. 因此更好的做法是把样式放到单独的⽂件中,然后通过读取⽂件的⽅式来加载样式
具体操作过程:
(1)创建qrc文件,通过qrc管理样式文件
(2)创建单独的qss文件,把这样的文件放到qrc中
(3)编写c++代码,读取qss文件中的内容,并设置样式


5.使⽤QtDesigner编辑样式
上面例子的功能在QtDesigner中直接集成了这样的功能,允许我们把样式直接写到.ui文件中


选择器

代码实例:

类选择器,不会对子类生效

id选择器

此时当类型选择器和id选择器选中同一个控件的时候,并且设置的样式是冲突的,此时id选择器的优先级更高,如果不冲突,两种样式会同时生效
并集选择器

⼦控件选择器(Sub-Controls)
有些控件内部包含了多个"⼦控件".⽐如QComboBox的下拉后的⾯板,⽐如QSpinBox的上下按钮 等
哪些控件拥有哪些⼦控件,参考⽂档QtStyleSheetsReference中ListofSub-Controls章节.
代码实例:设置下拉框的下拉按钮样式


伪类选择器(Pseudo-States)
上面介绍的选择器,都是选中"控件",伪类选择器,选中的是控件的状态,符合一定状态条件的控件

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

样式属性
QSS中的样式属性⾮常多,不需要都记住.核⼼原则还是⽤到了就去查. ⼤部分的属性和CSS是⾮常相似的. ⽂档的 Qt Style Sheets Reference 章节详细介绍了哪些控件可以设置属性,每个控 件都能设置哪些属性等.在翻阅⽂档的时候涉及到⼀个关键术语"盒模型"(BoxModel)
1.盒模型(BoxModel)

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

上述的复合属性,就是指如margin,包含margin-left,margin-right,margin-top,margin-bottom这四个属性

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

代码实例:设置外边距

运⾏程序,可以看到,当前按钮的边框被外边距挤的缩⼩了.但是获取到的按钮的Geometry 是不变的.
控件样式⽰例
1.按钮
代码实例:⾃定义按钮
创建一个按钮,右键改变样式表

color:设置文字颜色


2.复选框

代码实例:⾃定义复选框



3.输⼊框
代码实例::⾃定义单⾏编辑框


4.列表
代码实例:⾃定义列表框

5.菜单栏
代码实例:⾃定义菜单栏



6.登录界⾯

添加垂直布局管理器
将这些选中

选定控件修改高度,同时修改这两高度为同一值

当要给给这里设置背景时,直观想法是直接给QWidget顶层窗口设置背景图,但是Qt中存在限制,直接给顶层窗口设置背景会失效,因此这里可以给上述控件外头套上一个和窗口一样大小的QFrame控件,在Qt中设置背景图,除了background-image(图片固定大小)之外,还有border-image(图片会自动跟随控件的大小变化)属性

绘图
虽然Qt已经内置了很多的控件,但是不能保证现有控件就可以应对所有场景. 很多时候我们需要更强的"⾃定制"能⼒. Qt 提供了画图相关的API,可以允许我们在窗⼝上绘制任意的图形形状,来完成更复杂的界⾯设计.
所谓的"控件",本质上也是通过画图的⽅式画上去的. 画图API和控件之间的关系,可以类⽐成机器指令和⾼级语⾔之间的关系. 控件是对画图API的进⼀步封装;画图API是控件的底层实现
绘图API核⼼类

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

代码实例:绘制各种形状

这是定义在栈上的变量,不需要考虑释放的问题,此处指定的this不是父对象,而是指定绘制的设备
1.画线条


2.绘制矩形


3.绘制圆形


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


此处的0横坐标表示的是文字最左侧的位置
此处的100纵坐标表示的是文字的基线位置
5.设置画笔
通过QPen类可以设置画笔的线宽、颜⾊、样式、 画刷等。 画笔的颜⾊可以在实例化画笔对象时进⾏设置,画笔的宽度是通过setWidth()⽅法进⾏设置,画笔的 ⻛格是通过setStyle()⽅法进⾏设置,设置画刷主要是通过setBrush()⽅法。
• 设置画笔颜⾊:QPen::QPen(constQColor&color) 画笔的颜⾊主要是通过QColor类设置;
• 设置画笔宽度:voidQPen::setWidth(intwidth)
• 设置画笔⻛格:voidQPen::setStyle(Qt::PenStylestyle)


6 设置画刷
在Qt中,画刷是使⽤QBrush类来描述,画刷⼤多⽤于填充。QBrush定义了QPainter的填充模式, 具有样式、颜⾊、渐变以及纹理等属性。 画刷的格式中定义了填充的样式,使⽤Qt::BrushStyle枚举,默认值是Qt::NoBrush,也就是不进⾏ 任何填充。可以通过Qt助⼿查找画刷的格式。如下图⽰:

设置画刷主要通过voidQPen::setBrush(constQBrush&brush)⽅法,其参数为画刷的格式
