• Qt之QSS基础



    前言

      我们平时做的项目,应用程序界面非常美观,看起来十分炫酷,它是怎么实现的呢?本篇简单介绍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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    1、字体

    使用font设置字体。font的语法如下:

    font: [font-style] [font-variant] [font-weight] [font-size] [font-family]

    /* 按顺序设置,可以忽略其中某些值,例如:*/
    font: italic bold 12px arial, sans-serif;
    
    • 1
    • 2

    如果字体名字有空格则用双引号引起来,多个字体名字间用逗号分隔,如果第一个字体找不到则用第二个,依此类推。

    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);
    
    • 1

    其中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);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    渐变的坐标不是用具体像素表示,而是把渐变的坐标最小值定义为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;
    
    • 1
    • 2

    参数分别为:
    背景图路径
    背景图中最上面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
    
    • 1

    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'
    
    • 1
    • 2

    可以使用该方式实现很多效果,但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);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    2、QApplication 的对象调用setStyleSheet() 函数

    QSS作用域是整个程序里面的所有widget,如下:

    QApplication app(argc, argv);
    app.setStyleSheet(qss)
    
    • 1
    • 2

    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();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
  • 相关阅读:
    es入门教程
    JavaWeb--04YApi,Vue-cli脚手架Node.js环境搭建,创建第一个Vue项目
    北斗导航 | GBAS发展与应用支持CAT II/III类精密进近
    Rust -- 模式与匹配
    如何使用 NestJs、PostgreSQL、Redis 构建基于用户设备的授权验证
    算法|图论 2
    八、3d场景的区域光墙
    Eprime学习【E-basic语言、心理学实验程序设计】
    node+vue+mysql后台管理系统
    VHOST-SCSI代码分析(2)VHOST SCSI驱动分析
  • 原文地址:https://blog.csdn.net/u011832219/article/details/128183316