文章目录
前言
我们平时做的项目,应用程序界面非常美观,看起来十分炫酷,它是怎么实现的呢?本篇简单介绍QSS的使用,想要搞清楚原理,可以参考二狗大佬的博客。
QSS用于修改界面外观,如果通过QSS文件的方式加载,直接修改QSS文件就能看到效果变化,不需要编译。QSS与CSS十分相似。
一、基本语法
以QLabel为例,QSS实现如下:
QLabel {
/* 相当于 font: bold 50px "Snell Roundhand"; */
font-size: 50px;
font-weight: bold;
font-family: "Snell Roundhand";
/* 文本的颜色 */
color: white;
/* 相当于 background: lightgray url(:/resources/horizontal-add-line.png); */
background-color: lightgray;
background-image: url(:/resources/horizontal-add-line.png);
/* 还能使用渐变 */
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #FFFFFF, stop: 1 #BB000000);
/* 相当于 border: 5px solid gray; */
border-width: 5px;
border-color: gray;
border-style: solid;
/* 边框圆角 */
border-radius: 10px;
padding: 5px;
margin: 10px;
}
1、字体
使用font设置字体。font的语法如下:
font: [font-style] [font-variant] [font-weight] [font-size] [font-family]
/* 按顺序设置,可以忽略其中某些值,例如:*/
font: italic bold 12px arial, sans-serif;
如果字体名字有空格则用双引号引起来,多个字体名字间用逗号分隔,如果第一个字体找不到则用第二个,依此类推。
2、文本颜色
使用color设置文本颜色。可以直接写颜色,如:white;可以写rgb颜色数值,如:rgb(2,2,2) ;也可以写16进制颜色信息,如:#00FF00
3、背景
使用background设置背景,可以设置如下属性:
- background-color
- background-position
- background-repeat
- background-origin
- background-clip
- background-attachment
- background-image
比如:
background: lightgray url(:/resources/horizontal-add-line.png);
其中url的路径,可以是资源文件路径(:/开头)、绝对路径和相对路径。
background-repeat,用于设置重复,可选值如下:
- repeat-x:水平方向重复
- repeat-y:垂直方向重复
- no-repeat:不重复
background-position,用于设置选取的素材位置,可选值如下:
- top left
- top center
- top right
- center left
- center center
- center right
- bottom left
- bottom center
- bottom right
background-attachment,用于设置跟随滚动条滚动,可选值如下:
- scroll:背景随滚动条滚动
- fixed:背景不随滚动条滚动
background-color用于设置背景颜色,可以直接写入颜色,也支持渐变,渐变可选值如下:
- qlineargradient 线性渐变
- qradialgradient 辐射渐变
- qconicalgradient 角度渐变
比如:
/*
x1: 0, y1: 0,渐变的开始位置,为 border rectangle 的左上角(请参考盒子模型)
x2: 0, y2: 1,渐变的开始位置,为 border rectangle 的左下角
stop: 0.1 #FF0000,在 0.0 处渐变的颜色为 #FF0000
stop: 0.6 #00FF00,在 0.6 处渐变的颜色为 #00FF00
stop: 1.0 #0000FF,在 1.0 处渐变的颜色为 #0000FF
*/
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0.1 #FF0000,
stop: 0.6 #00FF00,
stop: 1.0 #0000FF);
渐变的坐标不是用具体像素表示,而是把渐变的坐标最小值定义为0,最大值定义为1,称为Normalization。其实,就是用比例表示,开始处用0表示,结束处用1表示,按比例计算实际的像素坐标。这样,就不需要关心像素坐标范围的具体值,不会因widget大小变化而变化。
除了使用background-image外,border-image也可以用于设置背景,区别在于,背景图和控件一样大时使用background-image,当不一样大时使用border-image。设置border-image,就一定要同时设置 border-width。用法如下:
border-width: 12px 12px 12px 12px;
border-image: url(:/img/round-button.png) 12 12 12 12 repeat stretch;
参数分别为:
背景图路径
背景图中最上面12px高的图像填充到widget的border-top
背景图中最右边12px宽的图像填充到widget的border-right
背景图中最下边12px高的图像填充到widget的border-bottom
背景图中最左边12px宽的图像填充到widget的border-left
水平方向的填充
垂直方向的填充。
后两个参数,可选值为:
- stretch:用拉伸的方式来填充边框背景图
- repeat:用平铺的方式填充边框背景图,当图片超过边界时则截断
- round:用平铺的方式填充边框背景图,图片会根据边框尺寸动态调整图片大小直至正好可以铺满整个边框
4、边框
使用border设置边框,用法如下:
border: border-width border-style border-color
border-style,边框风格,可选值如下:
- solid 实线边框
- dotted 点状边框
- none 无边框
- dashed 虚线
- double 双线
- groove 3D凹槽边框
- ridge 3D垄状边框
- inset 上光源3D
- outset 下光源3D
使用border-radius设置边框圆角,但是如果给定的半径大于对应边的一半,圆角就没有效果了,在 CSS 里没有这个问题。
遗憾的是,QSS不支持阴影。
5、文本居中、对齐
widget及其子类中使用宏Q_PROPERTY 定义的 WRITE 函数可以在 QSS 中访问,我们可以通过这种方式实现某些效果,比如:
- 设置文本居中:qproperty-alignment: AlignCenter,此外text-align不支持QLabel
- 设置文本:qproperty-text: ‘It is amazing’
- 设置对齐方式:
qproperty-alignment: 'AlignCenter'
qproperty-alignment: 'AlignBottom | AlignRight'
可以使用该方式实现很多效果,但qproperty-xxx 也不是万能的,在 :hover,:pressed 等伪类选择器中不生效。
二、加载QSS
1、widget对象调用setStyleSheet() 函数
QSS作用域是widget自己和它的所有子widget,如下:
QFrame *topFrame = new QFrame();
topFrame->setFrameShape(QFrame::StyledPanel);
topFrame->setFrameShadow(QFrame::Raised);
QPushButton *topButton = new QPushButton("Top Button");
QVBoxLayout *topLayout = new QVBoxLayout();
topLayout->addWidget(topButton);
topFrame->setLayout(topLayout);
QString qss = "QFrame {"
" background: #AAA;"
" border: 2px dashed gray;"
"}"
"QPushButton {"
" font-size: 20px;"
" padding: 5px 20px;"
" color: black;"
" border: 4px solid gray;"
" background-color: rgb(230, 250, 250);"
"}";
// 加载 QSS
topFrame->setStyleSheet(qss);
2、QApplication 的对象调用setStyleSheet() 函数
QSS作用域是整个程序里面的所有widget,如下:
QApplication app(argc, argv);
app.setStyleSheet(qss)
3、Qt Designer中的Change styleSheet…
QSS作用域是widget自己和它的所有子widget,与方式1相同,只是不需要自己编写具体代码,打开ui文件生成的代码,可以看到里面也是调用的setStyleSheet() 函数。
4、从文件中加载
如果在代码或设计师里面设置QSS,则每次修改,都需要重新编译,才能生效。所以,实际项目中,QSS的设置一般都写在文件中,代码中只调用setStyleSheet()函数。
void DlgFirst::loadUI()
{
QString filename = QString("%1/TmUI/First/dlgfirst.css").arg(g_strExeRoot);
QFile fileSkin(filename);
if(fileSkin.open(QIODevice::ReadOnly))
{
QString strSkin = QString::fromUtf8(fileSkin.readAll());
strSkin = strSkin.replace("@", g_CfgPath);
strSkin = strSkin.replace("~", g_strExeRoot);
this->setStyleSheet(strSkin);
fileSkin.close();
}
}