Qt--界面优化

在网页前端开发领域中, CSS 是一个至关重要的部分. 描述了一个网页的 "样式". 从而起到对网页美化的作用.现在的网页很难找到没有 CSS 的. 可以说让 "界面好看" 是一个刚需.网页开发作为 GUI 的典型代表, 也对于其他客户端 GUI 开发产生了影响. Qt 也是其中之一.Qt 仿照 CSS 的模式, 引入了 QSS, 来对 Qt 中的控件做出样式上的设定, 从而允许程序猿写出界面更好看的代码.同样受到 HTML 的影响, Qt 还引入了 QML 来描述界面, 甚至还可以直接把一个原生的 html 页面加载到界面上. 这部分内容咱们课堂上并不讨论.当然, 由于 Qt 本身的设计理念和网页前端还是存在一定差异的, 因此 QSS 中只能支持部分 CSS 属性.整体来说 QSS 要比 CSS 更简单一些.有时候可以通过QSS设置样式也可以通过C++设置样式,如果两者冲突,QSS优先级更高

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

选择器 {

属性名: 属性值;

}

QSS 沿用了这样的设定.

选择器 {

属性名: 属性值;

}

其中:

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

针对某个控件设置样式

cpp 复制代码
    ui->pushButton->setStyleSheet("QPushButton{color: #ffaa00;}");

针对全局控件设置样式

cpp 复制代码
this->setStyleSheet("QPushButton {color: #ffaa00;}");

如果设置了全局样式,然后在某个控件里又设置了其他的样式,会怎么样?叠加!

如果设置了全局样式,在某个控件里设置的样式和全局样式冲突了,会怎么样?自己优先

cpp 复制代码
    ui->pushButton->setStyleSheet("QPushButton { font-size: 50px}");
    ui->pushButton_2->setStyleSheet("QPushButton { color : blue}");

样式和代码分离

建一个qss文件,然后导包进来,在通过文件函数读取然后添加设置

style.qss

html 复制代码
QPushButton{
            color:red;
      }

main.cpp

cpp 复制代码
#include "widget.h"

#include <QApplication>
#include<QFile>
QString loadQSS()
{
    QFile file(":/style.qss");
    file.open(QFile::ReadOnly);
    QString style = file.readAll();
    file.close();
    return style;
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    //设置样式
    a.setStyleSheet(loadQSS());

    Widget w;
    w.show();
    return a.exec();
}

但是上个方案不好用,太麻烦了,仅供参考,Qt中有更好的方案,Qt Designer中直接集成这样的功能,允许我们把样式直接写到.ui文件里

a)右键空白,选择改变样式表(这里是全局设置,也可以右键控件对某一个控件单独设置)

b)添加样式并应用

由于设置样式太灵活,有很多地方都能设置,就导致当某个控件样式不符合预期的时候,排查起来就很麻烦

  1. 全局样式(QApplication设置的)
  2. 指定控件的样式(这个控件是否设置了样式)
  3. 指定控件的父控件的样式(有可能是父控件继承过来的)
  4. qss文件中的样式
  5. ui文件的样式

实际开发中,最好是统一使用某种方式来设置,方便排查

选择器

选择器概况
QSS 的选择器支持以下几种:

|-----------------------|-----------------------------------|-------------------------------------------------------------------|
| 选择器 | 示例 | 说明 |
| 全局选择器 | * | 选择所有的 widget. |
| 类型选择器 (type selector) | QPushButton | 选择所有的 QPushButton 和 其子类 的控件. |
| 类选择器 (class selector) | QPushButton | 选择所有的 QPushButton 的控件. 不会选择子类. |
| ID 选择器 | #pushButton_2 | 选择 objectName 为 pushButton_2 的控件. |
| 后代选择器 | QDialog QPushButton | 选择 QDialog 的所有后代(子控件, 孙子控件等等)中的 QPushButton. |
| 子选择器 | QDialog >QPushButton | 选择 QDialog 的所有子控件中的 QPushButton. |
| 并集选择器 | QPushButton, QLineEdit, QComboBox | 选择 QPushButton, QLineEdit, QComboBox 这三种控件. (即接下来的样式会针对这三种控件都生效). |
| 属性选择器 | QPushButtonflat="false" | 选择所有 QPushButton 中, flat 属性为 false 的控件. |

类型选择器

html 复制代码
a.setStyleSheet("QWidget {color: red;}");

对QWidget所有的子类和自己设置

类选择器

html 复制代码
    a.setStyleSheet(".QWidget {color: red;}");

仅对Widget设置而不对子类设置

ID选择器

cpp 复制代码
    QApplication a(argc, argv);
    QString style =" QPushButton {color: red;}";
    style +="#pushButton_2{color: green;}";
    style+="#pushButton_3{color:blue;}";
    a.setStyleSheet(style);

ID选择器的优先级要比类型选择器要高,冲突的话优先选择ID选择器内的样式,不冲突的话就是叠加

并集选择器

cpp 复制代码
     QApplication a(argc, argv);
    QString style = "#pushButton_2,QLineEdit,QLabel { color: red;}";
    a.setStyleSheet(style);

子控件选择器 (Sub-Controls)

有些控件内部包含了多个 "子控件" . 比如 QComboBox 的下拉后的面板, 比如 QSpinBox 的上下按钮等.可以通过子控件选择器 :: , 针对上述子控件进行样式设置.

cpp 复制代码
   QApplication a(argc, argv);
    QString style = "QComboBox::down-arrow{image:url(:/zhedie.png);}";
    a.setStyleSheet(style);

伪类选择器 (Pseudo-States)

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

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

使用: 的方式定义伪类选择器.

常用的伪类选择器

|------------|-----------|
| 伪类选择器 | 说明 |
| :hover | 鼠标放到控件上 |
| :pressed | 鼠标左键按下时 |
| :pressed | 获取输入焦点时 |
| :enabled | 元素处于可用状态时 |
| :checked | 被勾选时 |
| :read-only | 元素为只读状态时 |

cpp 复制代码
#include "widget.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QString style = "QPushButton {color: red;}";
    style += "QPushButton:hover { color: green;}";
    style+="QPushButton:pressed{color: blue;}";
    a.setStyleSheet(style);

    Widget w;
    w.show();
    return a.exec();
}

盒子模型 (Box Model)

在文档的 Customizing Qt Widgets Using Style Sheets 的 The Box Model 章节介绍了盒模型.

一个遵守盒模型的控件, 由上述几个部分构成.

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

默认情况下, 外边距, 内边距, 边框宽度都是 0.可以通过⼀些 QSS 属性来设置上述的边距和边框的样式.

|--------------|------------------------------------------------------|
| QSS 属性 | 说明 |
| margin | 设置四个方向的外边距. 复合属性. |
| padding | 设置四个方向的内边距. 复合属性. |
| border-style | 设置边框样式 |
| border-width | 边框的粗细 |
| border-color | 边框的颜色 |
| border | 复合属性, 相当于 border-style + border-width + border-color |

cpp 复制代码
    QApplication a(argc, argv);
    QString style = "QLabel {border: 20px solid red;vpadding-left: 50px;}";
    a.setStyleSheet(style);

属性小结

控件样式示例

下面给出一些常用控件的样式示例.

|------------------|---------------------------|
| 属性 | 说明 |
| font-size | 设置文字大小. |
| border-radius | 设置圆角矩形. 数值设置的越大, 角就 "越圆". |
| background-color | 设置背景颜色. |

给按钮设置样式

cpp 复制代码
QPushButton{
	font-size: 20px;
border:2px solid rgb(255, 199, 226);
border-radius: 30px;
background-color: rgb(255, 217, 223);
color:rgb(255, 255, 255);
}

QPushButton:pressed{
background-color:rgb(255, 126, 51)
}

给复选框添加样式

cpp 复制代码
QCheckBox{
	font-size:20px;
color:#f57464;
}

QCheckBox::indicator{
width:20px;

}

QCheckBox::indicator:unchecked{
image:url(:/or.png);
width: 50px;  
 height: 50px;

}

QCheckBox::indicator:unchecked:hover{
image:url(:/oror.png);
width: 50px;  
 height: 50px;
}

QCheckBox::indicator:unchecked:pressed{
image:url(:/okok.png);
width: 50px;  
 height: 50px;
}

QCheckBox::indicator:checked{
image:url(:/ok.png);
width: 50px;  
 height: 50px;
}

QCheckBox::indicator:checked:hover{

image:url(:/okok.png);
width: 50px;  
 height: 50px;
}

输入框

|----------------------------|--------------|
| 属性 | 说明 |
| border-width | 设置边框宽度. |
| border-radius | 设置边框圆角. |
| border-color | 设置边框颜色. |
| border-style | 设置边框风格. |
| padding | 设置内边距. |
| color | 设置文字颜色. |
| background | 设置背景颜色. |
| selection-background-color | 设置选中文字的背景颜色. |
| selection-color | 设置选中文字的文本颜色. |

html 复制代码
QLineEdit {
border-width:2px;
border-color:rgb(253, 214, 214);
border-style:solid;
border-radius:20px;
padding-left:10px;
color:rgb(245, 116, 100);
font: 25 11pt "DengXian";
background-color:rgb(255, 246, 253);
selection-color:rgb(255, 0, 255)
}

菜单栏

|-------------------------|-----------------|
| 要点 | 说明 |
| QMenuBar::item | 选中菜单栏中的元素. |
| QMenuBar::item:selected | 选中菜单来中的被选中的元素. |
| QMenuBar::item:pressed | 选中菜单栏中的⿏标点击的元素. |
| QMenu::item | 选中菜单中的元素 |
| QMenu::item:selected | 选中菜单中的被选中的元素. |
| QMenu::separator | 选中菜单中的分割线. |

html 复制代码
QMenuBar{

background-color:#f0aeae;
spacing:3px;
}

QMenuBar::item{
border-radius:6px;
padding:5px 5px;
background-color:#fdd6d6;
color:#f0aeae;
}

QMenuBar:item:selected{

background-color:#f57464;

}
QMenu::item{
color:#f0aeae;
border: 2px;
background-color:#fdd6d6;
padding: 2px;
}

QMenu::item:selected
{
border:2px solid #f0aeae;;
}
QMenu::separator{
height:2px;
background-color:#f0aeae;
margin: 5px;

}

登录界面

html 复制代码
/* 外层大背景框 */
QFrame#mainBgFrame{
    border-image:url(:/yunduan.png);
    border:0px;
}

/* 内层半透登录卡片,内层Frame的objectName必须写loginPanel */
QFrame#loginPanel{
    background-color:rgba(255,255,255,0.85);
    border-radius:14px;
    border:0px;
}
QLineEdit {
border-width:2px;
border-color:rgb(253, 214, 214);
border-style:solid;
border-radius:20px;
padding-left:10px;
color:rgb(245, 116, 100);
font: 25 11pt "DengXian";
background-color:rgb(255, 217, 223);
selection-color:rgb(255, 0, 255)

}
QPushButton{
	font-size: 20px;
border:2px solid rgb(255, 199, 226);
border-radius: 30px;
background-color: rgb(255, 217, 223);
color:rgb(255, 255, 255);
}

QPushButton:pressed{
background-color:rgb(255, 126, 51)
}
QCheckBox{
	font-size:20px;
color:#f57464;
}

QVBoxLayout{
background-color:rgba(255,255,255,0.7);
}
QCheckBox::indicator{
width:20px;

}

QCheckBox::indicator:unchecked{
image:url(:/or.png);
width: 50px;  
 height: 50px;

}

QCheckBox::indicator:unchecked:hover{
image:url(:/oror.png);
width: 50px;  
 height: 50px;
}

QCheckBox::indicator:unchecked:pressed{
image:url(:/okok.png);
width: 50px;  
 height: 50px;
}

QCheckBox::indicator:checked{
image:url(:/ok.png);
width: 50px;  
 height: 50px;
}

QCheckBox::indicator:checked:hover{

image:url(:/okok.png);
width: 50px;  
 height: 50px;
}

小结

  1. qss是类似于css的设置样式的机制
  2. qss的基本用法
  3. 选择器的使用
  4. 子空间选择器
  5. 伪类选择器
  6. 盒子模型
  7. 代码实例,qss支持的样式很多
相关推荐
(Charon)1 小时前
【C++】锁与原子操作(四):自旋锁的完整实现与性能优化
c语言·开发语言·c++
bu_shuo2 小时前
MATLAB中的meshgrid和ndgrid
开发语言·matlab
我命由我123453 小时前
Jetpack Compose - MaterialExpressiveTheme 与 MaterialTheme、ColorScheme
android·java·开发语言·java-ee·kotlin·android jetpack·android runtime
深海呐3 小时前
仓颉语言是ArkTs的上层语言吗?就像kotlin和Java
java·开发语言·kotlin·仓颉
白露与泡影3 小时前
聊聊物联网Java后端的核心技术难点(水表/电表/充电桩实战)
java·开发语言·物联网
gumichef3 小时前
第一章:面向对象核心——类和对象深度讲解
开发语言·c++
冷咖啡离 我的笨笨3 小时前
数据去重:通过 C# 删除 Excel 中的重复行
开发语言·c#·excel
ao-weilai3 小时前
C++基础:类和对象
开发语言·c++
Bryce学亮4 小时前
FileLine,基于 Qt 6 + QML 构建的跨平台文件传输与即时通讯工具
数据库·c++·人工智能·python·qt·github