Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >【QT】QT界面的美容院 -- QSS

【QT】QT界面的美容院 -- QSS

作者头像
IsLand1314
发布于 2025-04-15 05:24:38
发布于 2025-04-15 05:24:38
18800
代码可运行
举报
文章被收录于专栏:学习之路学习之路
运行总次数:0
代码可运行

一、背景介绍

🔥 在网页前端开发领域中,CSS 是一个至关重要的部分,描述了一个网页的 “样式”,从而起到对网页 美化 的作用。

网页开发作为 GUI 的典型代表,也对于其他客户端 GUI 开发产生了影响,Qt 也是其中之一。

  • Qt 仿照 CSS 的模式,引入了 QSS,来对 Qt 中的控件做出样式上的设定,从而允许我们写出界面更好看的代码。
  • 同样受到 HTML 的影响,Qt 还引入了 QML 来描述界面,甚至还可以直接把一个原生的 html 页面加载到界面上。
  • 当然,由于 Qt 本身的设计理念和网页前端还是存在一定差异的,因此 QSS 中只能支持部分 CSS 属性。整体来说 QSS 要比 CSS 更简单一些。

注意:如果通过 QSS 设置的样式和通过 C++ 代码设置的样式冲突,则 QSS 优先级更高。

二、基本语法

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

QSS 沿用了其设定:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
选择器 {
    属性名: 属性值; 
}

其中:

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

例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
QPushButton { color: red; }
//或者:
QPushButton {
    color: red;
}
  • 上述代码的含义表示,针对界面上所有的 QPushButton,都把文本颜色设置为红色

编写 QSS 时使用单行 和多行的格式均可。

【基本使用】

新建项目,以 Widget 作为基类,构造函数代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    QGridLayout* layout = new QGridLayout();

    QPushButton* button1 = new QPushButton("红色");
    QPushButton* button2 = new QPushButton("无色");

    button1->setStyleSheet("QPushButton{color:red;}");
    layout->addWidget(button1, 0, 0);
    layout->addWidget(button2, 0, 1);

    this->setLayout(layout);
}

结果如下:

image-20250201160501449
image-20250201160501449

**注意:**上述代码中,只针对这一个按钮通过 setStyleSheet 方法设置的样式,此时这个样式仅针对该按钮生效。如果创建其他按钮,其他按钮不会受到影响。

三、基本语法

1. 指定控件样式设置

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

  • 另一方面,给指定控件设置样式之后,该控件的子元素也会受到影响。

【子元素受到影响】

A. 在界面上创建两个按钮和一个单行编辑框

B. 修改 widget.cpp

这次不再给按钮设置样式,而是给 Widget 设置样式(Widget 是 QPushButton 的父控件)

image-20250201163646291
image-20250201163646291
  • 可以看到 样式 对于 this 的子控件按钮同样会生效,但是必须是和选择器相关的
2. 全局样式设置

可以通过 QApplicationsetStyleSheet 方法设置整个程序的全局样式。

全局样式优点:

  • 使同一个样式针对多个控件生效,代码更简洁。
  • 把界面上所有控件样式内聚在⼀起,便于维护和问题排查。
image-20250201180411861
image-20250201180411861
3. 样式的层叠特性

如果通过 全局样式 给某个控件设置了属性 1,通过 指定控件样式 给控件设置属性 2,那么这两个属性都会产生作用

比如:基于上面全局样式的设计,我们给 按钮1 设置字体大小,如下:

image-20250201180624931
image-20250201180624931

可以看到,对于第一个按钮来说,同时具备了颜色和字体大小样式,而第二个按钮只有颜色样式。

说明针对第一个按钮,两种设置方式设置的样式叠加起来了。

  • 形如上述这种属性叠加的效果被称为 “层叠性”

CSS 全称为 Cascading Style Sheets,其中 Cascading 就是 “层叠性” 的意思,QSS 也继承了这样的设定。实际上把 QSS 叫做 QCSS 也许更合适一些。

注意:局部样式无法叠加,除非写到一行中,如下:

image-20250201181111911
image-20250201181111911
4. 样式优先级

如果全局样式和指定控件样式冲突,则指定控件样式优先展示

  • 这里就不做演示了

在 CSS 中也存在类似的优先级规则。通常来说都是 “局部” 优先级高于 “全局” 优先级,相当于全局样式先 “奠定基调”,再通过指定控件样式来 “特事特办”。

  • 实际开发中,可以在全局样式中设置比较通用的样式来统一整个程序的界面风格。
  • 如果 需要针对某个控件进行微调,可以使用局部样式来做出调整
5. 从文件加载样式表

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

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

操作如下:

A. 在界面上创建一个按钮

B. 创建 resource.qrc 文件(Qt -> Qt Resource File),并设定前缀为 /

img
img

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

  • style.qss 是需要程序运行时加载的,为了规避绝对路径的问题,仍然使用 qrc 的方式来组织(即把资源文件内容打包到 cpp 代码中)
  • Qt Creator 没有提供创建 qss 文件的选项,直接 “右键” -> “新建” -> “文本文档”,手动设置文件扩展名为 qss 即可
image-20250202112632742
image-20250202112632742

使用 Qt Creator 打开 style.qss,编写内容

image-20250202112750370
image-20250202112750370

新增一个函数来加载样式,如下:

image-20250202113026885
image-20250202113026885

理论上来说 Qt 应该要提供直接从文件加载样式表的接口。

  • 类似于 setStyleSheetFromFile(const QString& path) 这种,在内部把读文件操作封好。
6. 使用 Qt Designer 编辑样式表

QSS 也可以通过 Qt Designer 直接编辑,从而起到 实时预览的效果

  • 同时也能避免 C++ 和 QSS 代码的 耦合
image-20250202113445075
image-20250202113445075

如下:

image-20250202113543789
image-20250202113543789

这种方式设置样式,样式内容会被以 xml 格式记录到 ui 文件中,如下:

img
img

同时在控件的 styleSheet 属性中也会体现:

img
img

💡 由于设置样式太灵活,有很多地方都能设置,所以当我们发现一个控件的样式不符合预期的时候,要记得排查这几个地方:

  • 全局样式(QAppplication 设置的)
  • 指定控件样式(这个控件是否设置了样式)
  • 指定控件的父控件的样式(可能是从父控件继承过来的)
  • qss 文件中的样式
  • ui 文件中的样式

在实际开发中,如果需要设置样式,建议最好 统一使用某一种方式 来设置。

四、选择器

1. 选择器概况

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 这三种控件。(即接下来的样式会针对这三种控件都生效)。

属性选择器

QPushButton[flat="false"]

选择所有 QPushButton 中,flat 属性为 false 的控件。

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

【使用类型选择器选中子类控件】

① 在界面上创建一个按钮,修改 main.cpp,设置全局样式

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
a.setStyleSheet("QWidget{color:red;}");
  • 注意 :此处选择器使用的是 QWidget。QPushButton 也是 QWidget 的子类,所以会受到 QWidget 选择器的影响。
image-20250202134425319
image-20250202134425319
  • 可以看到按钮的文本颜色已经是红色了

② 但是 💢如果把上述样式代码修改为下列代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
a.setStyleSheet(".QWidget{color:red;}");
【使用 id 选择器】

在开发中,如果期望不同的控件样式不同,此时就需要使用到 ID 选择器了

① 在界面上创建 3 个按钮,objectName 为 pushButton、pushButton_2、pushButton_3

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

  • 先通过 QPushButton 设置所有的按钮为红色。
  • 再通过 #pushButton#pushButton_2 分别设置这两个按钮为绿色和黄色。
image-20250202135015078
image-20250202135015078

当某个控件身上,通过类型选择器和 ID 选择器 设置了冲突的样式 时,ID 选择器样式优先级更高(遵循局部优先)

同理,如果是其他的多种选择器作用同一个控件时出现冲突的样式,也会涉及到优先级问题。Qt 文档上有具体的优先级规则介绍(参见 The Style Sheet Syntax 的 Conflict Resolution 章节)

img
img

这里的规则计算起来非常复杂(CSS 中也存在类似的设定)。可以简单的认为,选择器描述的范围越精准,则优先级越高。一般来说,ID 选择器优先级是最高的。

如果属性不冲突,还是会同时生效

【使用并集选择器】

创建三个按钮、一个 label、一个单行输入框,编写 main.cpp,设置全局样式

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
QString style="QPushButton,QLineEdit,QLabel{color:red;}";
 
a.setStyleSheet(style);

此时就可以看到这三种控件的文字颜色都设置为了红色:

  • 并集选择器是一种很好的代码复用的方式,很多时候我们希望界面上的多个元素风格是统一的,就可以使用并集选择器,把样式属性同时指定给多种控件。

也可以指定 id 选择器:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
QString style="#pushButton_2,QLineEdit,QLabel{color:red;}";
image-20250202140539465
image-20250202140539465
2. 子控件选择器(Sub-Controls)

有些控件内部包含了多个 “子控件”,比如 QComboBox 的下拉后的面板,比如 QSpinBox 的上下按钮等。

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

哪些控件拥有哪些子控件,参考文档 Qt Style Sheets Reference 中 List of Sub-Controls 章节

img
img

【设置下拉框的下拉按钮样式】

① 在界面上创建一个下拉框,并创建几个选项

image-20250202141045752
image-20250202141045752

② 创建 resource.qrc,并导入图片 downPull.png

image-20250202141150914
image-20250202141150914
img
img

③ 修改 main.cpp,编写全局样式

  • 使用子控件选择器 QComboBox::down-arrow 选中了 QComboBox 的下拉按钮。
  • 再通过 image 属性设置图片。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
QString style="QComboBox::down-arrow{ image:url(:/downPull.png)}";
a.setStyleSheet(style);

结果如下:

image-20250202141519724
image-20250202141519724
3. 伪类选择器(Pseudo-States)

伪类选择器,是根据 控件所处的某个状态 被选择的。

例如按钮被按下,输入框获取到焦点,鼠标移动到某个控件上等。

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

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

常用的伪类选择器:

伪类选择器

说明

:hover

鼠标放到控件上

:pressed

鼠标左键按下时

:focus

获取输入焦点时

:enabled

元素处于可用状态时

:checked

被勾选时

:read-only

元素为只读状态时

这些状态可以使用 ! 来取反,比如 :!hover 就是鼠标离开控件时,:!pressed 就是鼠标松开时,等等。更多伪类选择器的详细情况可以参考 Qt Style Sheets Reference 的 Pseudo-States 章节。

【设置按钮的伪类样式】

在界面上创建一个按钮,编写 main.cpp,创建 全局样式

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
QString style = "QPushButton { color: red; }";
style += "QPushButton:hover { color: green; }";
style += "QPushButton:pressed { color: blue; }";

a.setStyleSheet(style);

运行程序,结果如下:

img
img
  • 可以看到默认情况下按钮文字是红色,鼠标移动上去是绿色,鼠标按下按钮是蓝色

上述代码也可以使用事件的方式来实现。

【使用事件方式实现同样效果】

① 创建 MyPushButton 类,继承自 QPushButton

② 把生成代码中的构造函数 改成带参数 QWidget* 版本的构造函数(否则无法和 Qt Designer 生成的代码适配),如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// mypushbutton.h
#include <QPushButton>
 
class MyPushButton : public QPushButton
{
public:
    MyPushButton(QWidget* parent);
};
 
 
 
// mypushbutton.cpp
#include "mypushbutton.h"
MyPushButton::MyPushButton(QWidget* parent) : QPushButton(parent)
{
 
}

③ 在界面上创建按钮,并提升为 MyPushButton 类型

  • 右键按钮,选择 “提升为…”
  • 填写提升的类名和头文件:
img
img

提升完毕后,在右侧对象树这里,就可以看到类型的变化。

img
img

④ 重写 MyPushButton 的四个事件处理函数

a. 修改 mypushbutton.h

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class MyPushButton : public QPushButton
{
public:
    MyPushButton(QWidget* parent);
 
    void mousePressEvent(QMouseEvent* e);
    void mouseReleaseEvent(QMouseEvent* e);
    void enterEvent(QEvent* e);
    void leaveEvent(QEvent* e);
};

b. 修改 mypushbutton.cpp

  • 初始化设为红色
  • 鼠标进入时设为绿色,离开是还原红色
  • 鼠标按下时设为蓝色,松开时还原绿色(松开时鼠标还是在按钮里)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
MyPushButton::MyPushButton(QWidget* parent) : QPushButton(parent)
{
    this->setStyleSheet("QPushButton { color: red; }");
}
 
void MyPushButton::mousePressEvent(QMouseEvent *e)
{
    this->setStyleSheet("QPushButton { color: blue; }");
}
 
void MyPushButton::mouseReleaseEvent(QMouseEvent *e)
{
    this->setStyleSheet("QPushButton { color: green; }");
}
 
void MyPushButton::enterEvent(QEvent *e)
{
    this->setStyleSheet("QPushButton { color: green; }");
}
 
void MyPushButton::leaveEvent(QEvent *e)
{
    this->setStyleSheet("QPushButton { color: red; }");
}
  • 运行程序可以看到效果和上述案例一致

很明显,实现同样的功能,伪类选择器要比事件的方式简单很多。 但是不能就说事件机制就不好,事件可以完成的功能很多,不仅仅是样式的改变,还可以包含其他业务逻辑,这一点是 伪类选择器 无法替代的。

五、样式属性

QSS 中的样式属性非常多,大部分的属性和 CSS 是非常相似的。

  • 文档的 Qt Style Sheets Reference 章节详细介绍了哪些控件可以设置属性,每个控件都能设置哪些属性等。
image-20250202143545891
image-20250202143545891
1. 盒模型(Box Model)
  • 这个词 主要来自于 CSS

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

img
img

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

  • Content 矩形区域:存放控件内容,比如包含的文本 / 图标等。
  • Border 矩形区域:控件的边框。
  • Padding 矩形区域:内边距,边框和内容之间的距离。
  • Margin 矩形区域:外边距,边框到控件 geometry 返回的矩形边界的距离。
  • 默认情况下,外边距、内边距、边框宽度都是 0。

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

QSS 属性

说明

margin

设置四个方向的外边距。复合属性。

padding

设置四个方向的内边距。复合属性。

border-style

设置边框样式

border-width

边框的粗细

border-color

边框的颜色

这里的复合属性:由多个属性构成,margin 可以拆成如下:

  • margin-left
  • margin-right
  • margin-top
  • margin-bottom

当然实际运用的时候,写 margin: 10px; ==> 表示四个方向都是 10px 的外边距,而写 margin: 10px 20px; 则是上下都是 10px, 左右是 20px, margin: 10px 20px 30px 40px ==> 上右下左(顺时针)

  • 同样 padding 也可以拆成 4 个属性的

【设置边框和内边距】

在界面上创建一个 label,修改 main.cpp, 设置全局样式

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
QString style = "QLabel{border: 20px solid green; padding-left: 50px}";
a.setStyleSheet(style);
  • border: 20px solid green 相当于 border-style: solid; border-width: 2px; border-color: green; 三个属性的简写形式。
  • padding-left: 50px; 是给左侧设置内边距。

结果如下:

image-20250202144713960
image-20250202144713960

【设置外边距】

为了方便确定控件位置,演示外边距效果,使用代码创建⼀个按钮。修改 widget.cpp,创建按钮,并设置样式

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    QPushButton* button = new QPushButton(this);
    button->setGeometry(0, 0, 100, 100);
    button->setText("按钮");
    button->setStyleSheet("QPushButton{border: 5px solid red; margin: 20px}");

    qDebug() << button->geometry();
}

运行程序如下:

image-20250202151310020
image-20250202151310020

可以看到,当前按钮的边框被外边距挤的缩小了,但是获取到的按钮的 Geometry 是不变的。

2. 控件样式示例(Box Model)
① 自定义按钮

A. 界面上创建一个按钮

B. 右键 -> 改变样式表,使用 Qt Designer 设置样式

img
img

C. 执行程序,点击 “按钮”:

img
img

属性

说明

font-size

设置文字大小。

border-radius

设置圆角矩形。 数值设置的越大,角就越圆。

background-color

设置背景颜色。

② 自定义复选框

A. 创建一个 resource.qrc 文件,并导入以下图片

image-20250202152808327
image-20250202152808327
image-20250202152837718
image-20250202152837718
image-20250202152850132
image-20250202152850132
image-20250202152857961
image-20250202152857961
image-20250202152904725
image-20250202152904725
image-20250202152912954
image-20250202152912954
  • 使用黑色作为默认形态
  • 使用蓝色作为 hover 形态
  • 使用红色作为 pressed 形态

⚽ 使用阿里矢量图标库,可以下载到上述图片,下载的时候可以手动选择颜色

注意这里的文件命名。

image-20250202153026411
image-20250202153026411

B. 创建一个复选框,并且用样式表来编辑复选框的样式

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
QCheckBox {
    font-size: 20px;
}
 
QCheckBox::indicator {
    width: 20px;
    height: 20px;
}
 
QCheckBox::indicator:unchecked {
    image: url(:/checkbox-unchecked.png);
}
 
QCheckBox::indicator:unchecked:hover {
    image: url(:/checkbox-unchecked_hover.png);
}
 
QCheckBox::indicator:unchecked:pressed {
    image: url(:/checkbox-unchecked_pressed.png);
}
 
QCheckBox::indicator:checked {
    image: url(:/checkbox-checked.png);
}
 
QCheckBox::indicator:checked:hover {
    image: url(:/checkbox-checked_hover.png);
}
 
QCheckBox::indicator:checked:pressed {
    image: url(:/checkbox-checked_pressed.png);
}
  • 鼠标点击选中,再取消的过程,可以看到此时的复选框就变得丰富起来了:
img
img

要点

说明

::indicator

子控件选择器。 选中 checkbox 中的对钩部分。

:hover

伪类选择器。 选中鼠标移动上去的状态。

:pressed

伪类选择器。 选中鼠标按下的状态。

:checked

伪类选择器。 选中 checkbox 被选中的状态。

:unchecked

伪类选择器。 选中 checkbox 未被选中的状态。

width

设置子控件宽度。 对于普通控件无效(普通控件使用 geometry 方式设定尺寸)。

height

设置子控件高度。 对于普通控件无效(普通控件使用 geometry 方式设定尺寸)。

image

设置子控件的图片。 像 QSpinBox, QComboBox 等可以使用这个属性来设置子控件的图片。

③ 自定义单选框

A. 创建 resource.qrc 文件,并导入以下图片

img
img

  • 使用黑色作为默认形态
  • 使用蓝色作为 hover 形态
  • 使用红色作为 pressed 形态

B. 在界面上创建两个单选按钮,并且在 Qt Designer 中编写样式

  • 此处为了让所有 QRadioButton 都能生效,把样式设置在 Widget 上了,并且使用后代选择器选中了 QWidget 里面的 QRadioButton。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 QWidget QRadioButton {
    font-size: 20px;
}
 
QWidget QRadioButton::indicator {
    width: 20px;
    height: 20px;
}
 
QWidget QRadioButton::indicator:unchecked {
    image: url(:/radio-unchecked.png);
}
 
QWidget QRadioButton::indicator:unchecked:hover {
    image: url(:/radio-unchecked_hover.png);
}
 
QWidget QRadioButton::indicator:unchecked:pressed {
    image: url(:/radio-unchecked_pressed.png);
}
 
QWidget QRadioButton::indicator:checked {
    image: url(:/radio-checked.png);
}
 
QWidget QRadioButton::indicator:checked:hover {
    image: url(:/radio-checked_hover.png);
}
 
QWidget QRadioButton::indicator:checked:pressed {
    image: url(:/radio-checked_pressed.png);
}

运行程序,如下:

img
img

注意 :

  • QSS 中有些属性,子元素能继承父元素(例如 font-size、color 等),但是也有很多属性是不能继承的。
  • 具体哪些能继承哪些不能继承,规则比较复杂,我们不去具体研究,实践中我们编写更精准的选择器是上策。
④ 自定义输入框

A. 在界面上创建一个单行编辑框,在 Qt Designer 中编写样式

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
QLineEdit {
 border-width: 2px; 
 border-radius: 20px;
 border-color: rgb(170, 170, 255);
 border-style: solid;
 padding: 0 8px;
 color: rgb(170, 85, 127);
 background:rgb(220, 220, 225);
 selection-background-color: rgb(0, 180, 0);
 selection-color: rgb(180, 0, 0);
}

B. 执行程序,输入文本,并且选中 :

image-20250202161340303
image-20250202161340303

属性

说明

border-width

设置边框宽度。

border-radius

设置边框圆角。

border-color

设置边框颜色。

border-style

设置边框风格。

padding

设置内边距。

color

设置文字颜色。

background

设置背景颜色。

selection-background-color

设置选中文字的背景颜色。

selection-color

设置选中文字的文本颜色。

  • 这里 background 其实也可以用 background-color 的
⑤ 自定义列表

A. 在界面上创建一个 ListView,然后在样式表中编写代码,如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
QListView::item:hover {
 background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
 stop: 0 #FAFBFE, stop: 1 #DCDEF1);
}
QListView::item:selected {
 border: 1px solid #6a6ea9;
 background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
 stop: 0 #6a6ea9, stop: 1 #888dd9);
}

B. 然后将其变形成为 ListWidget,然后右击进行编辑项目,如下:

image-20250202155239152
image-20250202155239152

C. 执行程序,结果如下:

image-20250202155328463
image-20250202155328463

要点

说明

::item

选中 QListView 中的具体条目。

:hover

选中鼠标悬停的条目

:selected

选中某个被选中的条目。

background

设置背景颜色

border

设置边框。

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 进行渐变的。

举个例子:

现在新建一个项目,界面不创建任何任何控件,编写样式,如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
QWidget {
    background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop: 0 #fff, stop: 1 #000);
}

修改代码》让其当前按照水平从左往右从白色过渡到黑色

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
QWidget {
    background-color: qlineargradient(x1:0, y1:0, x2:1, y2:0, stop: 0 #fff, stop: 1 #000);
}

⑥ 自定义菜单栏

A. 创建菜单栏,创建若干菜单项和一个分隔符:

B. 编写样式表,如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
QMenuBar {
    background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 lightgray, stop:1 darkgray);
    spacing: 3px;
}
 
QMenuBar::item {
    padding: 1px 4px;
    background: transparent;
    border-radius: 4px;
}
 
QMenuBar::item:selected {
    background: #a8a8a8;
}
 
QMenuBar::item:pressed {
    background: #888888;
}
 
QMenu {
    background-color: white;
    margin: 0 2px;
}
 
QMenu::item {
    padding: 2px 25px 2px 20px;
    border: 3px solid transparent;
}
 
QMenu::item:selected {
    border-color: darkblue;
    background: rgba(100, 100, 100, 150);
}
 
QMenu::separator {
    height: 2px;
    background: lightblue;
    margin-left: 10px;
    margin-right: 5px;
}

执行代码,结果如下:

img
img

要点

说明

QMenuBar::item

选中菜单栏中的元素。

QMenuBar::item:selected

选中菜单栏中的被选中的元素。

QMenuBar::item:pressed

选中菜单栏中的鼠标点击的元素。

QMenu::item

选中菜单中的元素

QMenu::item:selected

选中菜单中的被选中的元素。

QMenu::separator

选中菜单中的分割线。


⑦ 登录界面
  • 【基于上述学习的 QSS 样式,来制作一个美化版本的登录界面】

A. 在界面上创建元素,并使用 布局管理器 把相关元素包裹一下

image-20250202162524988
image-20250202162524988
  • 使用 QVBoxLayout 来管理上述控件。
  • 两个输入框和按钮的 minimumHeight 均设置为 30(元素在布局管理器中无法直接设置 width 和 height,使用 minimumWidthminimumHeight 代替,此时垂直方向的 sizePolicy 要设为 fixed)。
image-20250202162517629
image-20250202162517629
  • 右键 QCheckBox,选择 Layout Alignment 可以设置 checkbox 的对齐方式(左对齐,居中对齐,右对齐)。

设置背景图片

创建 qrc 文件,导入背景图

image-20250202162949777
image-20250202162949777
  • 第一想法:直接给 QWidget 顶层窗口设置背景图,但是 Qt 中存在限制 QWidget的顶层窗口 无法设置背景图片
  • 因此可以再套上一层 QFrame,背景图片就设置到 QFrame 上即可。
image-20250202163259469
image-20250202163259469

编写 QFrame 的 QSS 样式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
QFrame{
   border-image:url(:/ship.jpg);
}
  • 使用 border-image 设置背景图片,而不是 background-image
  • 主要是因为 border-image 是可以自动缩放的,这一点在窗口大小发生改变时是非常有意义的。

效果如下:

image-20250202163538677
image-20250202163538677

编写 CSS 代码(样式表):

  • 背景色使用 transparent 表示完全透明(应用父元素的背景)。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
QFrame{
   border-image:url(:/ship.jpg);
}

QLineEdit {
    color: #8d98a1;
    background-color: #405361;
    padding: 0 5px;
    font-size: 20px;
    border-style: none;
    border-radius: 10px;
}
 
QCheckBox {
    color: white;
    background-color: transparent;
}
 
QPushButton {
    font-size: 20px;
    color: white;
    background-color: #5555;
    border-style: outset;
    border-radius: 10px;
}
 
QPushButton:pressed {
    color: black;
    background-color: #ced1db;
    border-style: inset;
}

然后还需要对两个输入框的 ui 做点改变,如下:

img
img

运行程序,最终效果如下:

image-20250202164239999
image-20250202164239999
  • 最终完整样式代码,这些代码设置到 QFrame 的属性中即可。通常我们建议把样式代码集中放置,方便调整和排查。

六、小结

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

  • 在 CSS 中,整个网页的样式都是 CSS 一手负责,CSS 功能更强大,并且也更可控。
  • 相比之下,Qt 中是以原生 API 为主,来控制控件之间的尺寸、位置等,QSS 只是起到辅助的作用。
  • 而且 Qt 中提供的一些 “组合控件”(像 QComboBox、QSpinBox 等)内部的结构是不透明的,此时进行一些样式设置也会存在一定的局限性。

另外,做出好看的界面,光靠 QSS 是不够的,更重要的是需要 专业美工做出设计稿

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-04-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【QT】QSS
在widget.cpp中使用setStyleSheet方法设置样式 这属于是给Widget设置样式,这对于子控件QPushButton等也会生效
s-little-monster
2024/11/18
1170
【QT】QSS
【Qt】QSS
上述代码的含义表示,针对界⾯上所有的 QPushButton , 都把⽂本颜⾊设置为红色。
YoungMLet
2024/08/15
1971
【Qt】QSS
Qt编写自定义控件70-扁平化flatui
对于现在做前端开发人员来说,FlatUI肯定不陌生,最近几年扁平化的设计越来越流行,大概由于现在PC端和移动端的设备的分辨率越来越高,扁平化反而看起来更让人愉悦,而通过渐变色产生的质感色彩反而没有扁平化来得亲切。
feiyangqingyun
2019/10/16
2.1K0
Qt编写自定义控件70-扁平化flatui
C++ Qt开发:PushButton按钮组件
Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍QPushButton按钮组件的常用方法及灵活运用。
王瑞MVP
2023/12/12
1.1K0
C++ Qt开发:PushButton按钮组件
【QT】QT样式表语法
Qt样式表是一个可以自定义部件外观的强大机制,样式表的概念、术语、语法均受到HTML层叠样式表(CSS)的启发。
半生瓜的blog
2023/05/13
1.7K0
【QT】QT样式表语法
初学Qt不会样式表怎么办,打包好的Qt样式表一键生成送给你。
       很多人应该和我一样,想做界面才接触的Qt,结果就是做不出来华丽的界面,想给控件上个色?不会,百度半天,好不容易给控件添加了背景色,下一个控件又不会了,别急,这次福利来了,我将平时用到的样式表做了一个总结,并做了一个一键生成,调节数据就可以实时显示,里面包括了Label,LineEdit,PushButton,CheckBox,RadioButton,ScrollBar,Slider,Progressbar,Tabwidget,ToolBox,TabWidget控件的自定义。代码很简单,就是重复写槽函数,但其对于新手的学习很有帮助,避免了盲目,大量的通过百度数据拼接样式表。一来方便学习,所以参数都写在左下角,方便了解到使用了什么生成了什么,二来不用重复造轮子,调节后,可直接将左下角生成的QSS代码复制到qt的样式表里面即可显示效果。可能有一些人会说这是一种偷懒,让人逐渐不想学习,只能说智者见智仁者见仁吧。
花狗Fdog
2020/10/28
5.1K0
初学Qt不会样式表怎么办,打包好的Qt样式表一键生成送给你。
Qt Style Sheet实践(三):QCheckBox和QRadioButton
导读       单选按钮(QRadioButton)和复选框(QCheckBox)是界面设计中的重要元素。单选按钮只允许用户在一组选项中选择一个,且当其中一个被选中的时候,按钮组中的其他单选按钮自动取消。复选框则可以让用户同时选中多个选项,这在多项选择的情况下非常有用。此外,复选框经过设置还具备第三种状态:未决状态(partially checked)。单选按钮和复选框应用广泛,在WEB表单、软件配置界面常常是不可或缺的元素。这篇博文主要讲述Qt中单选按钮和复选框如何通过样式表进行外观定制。 基本实现  
24K纯开源
2018/01/18
10.1K0
Qt Style Sheet实践(三):QCheckBox和QRadioButton
Qt开源作品9-扁平化样式flatui
对于现在做前端开发人员来说,FlatUI肯定不陌生,最近几年扁平化的设计越来越流行,大概由于现在PC端和移动端的设备的分辨率越来越高,扁平化反而看起来更让人愉悦,而通过渐变色产生的质感色彩反而没有扁平化来得亲切。
feiyangqingyun
2020/05/14
1.2K0
Qt开源作品9-扁平化样式flatui
Qt Style Sheet实践(一):按钮及关联菜单
导读      正如web前端开发中CSS(Cascade Style Sheet)的作用一样,Qt开发中也可以使用修改版的QSS将逻辑业务和用户界面进行隔离。这样,美工设计人员和逻辑实现者可以各司其职而不受干扰。更重要的是,由于界面和逻辑处理是分离的,低耦合性使得代码重构的工作量可以减少到最小。QSS和CSS的语法几乎一致,除了Qt自身增加的一些属性之外,其余的属性都可以在CSS2或CSS3中找到对应的属性。因此,如果曾经有过CSS的使用经验,那么QSS的使用将游刃有余。关于QSS的使用实践,打算撰写一系
24K纯开源
2018/01/18
4.8K0
Qt Style Sheet实践(一):按钮及关联菜单
qt 如何设计好布局和漂亮的界面。
​       曾几何时,我们都在黑框框下度过,我们受够了被黑框框支配的恐惧,想要跳出去,去看看外面,我们听够了类似于界面只是皮肤,背后的代码才是王道的话语,当你觉得黑框框已经满足不了你的时候,我觉得,你是时候做出一些改变了。如果你是学习C++的,我想qt可以作为你进入界面的一条选择,这篇文章,我们不讲函数,不讲类,总之就是不讲代码,我们来讲讲代码之外,聊一聊关于怎么布局,怎么用qt做出一个漂亮的界面❤️。 ​       我在一篇讲布局博文下面看到这样一句评论:为什么非要布局,直接自己摆不是更好吗?我相信很多刚接触布局的同学,都有这种想法,当然,当初的我和你们拥有一样的想法,但是现在,这种想法我不敢再有。之所以会说出这句话,要么是刚接触界面,要么是随手点了进来,阿巴阿巴看完评论了一句。刚开始接触界面,布局确实不是那么重要,我们的软件(都称不上是软件,就是一个空壳子)一共也没几个组件,两个按钮?三个文本框?刚接触的时候,你是否考虑过软件大小随意变化的问题,你是否考虑过后期添加组件,随着我们的软件越来越庞大,让组件自动分配空间显的尤为重要。
花狗Fdog
2020/10/28
10.4K0
qt 如何设计好布局和漂亮的界面。
Qt Theme 纯 qss 的 Qt 主题
源码地址:https://github.com/hubenchang0515/QtTheme/
用户2270320
2025/03/11
2010
Qt Theme 纯 qss 的 Qt 主题
QListWidget的QSS用法「建议收藏」
https://blog.csdn.net/u011125673/article/details/51753997
全栈程序员站长
2022/09/06
5.2K0
QListWidget的QSS用法「建议收藏」
QPushButton 基本使用
PyQt 提供了多种按钮类,用于创建各种类型的按钮。这一部分将打算介绍一下 PyQt 各种 Button 及相关类,并扩展 Button 的功能用法,让你能够打造自己的个性化 Button 。在下面,我先来介绍 PyQt 中常用的按钮类及其主要特点:
繁依Fanyi
2023/10/12
7610
QPushButton 基本使用
Python:PyQt学习
上面的代码把控件对应的变量名全部作为全局变量。如果要设计稍微复杂一些的程序,就会出现太多的控件对应的变量名。而且这样也不利于代码的模块化。所以,我们通常应该把 一个窗口和其包含的控件,对应的代码全部封装到类中,如下所示:
小简
2023/01/04
10.7K0
Python:PyQt学习
Qt编写自定义控件27-颜色按钮面板
颜色按钮面板主要用在提供一个颜色按钮面板,用户单击某个按钮,然后拿到对应的颜色值,用户可以预先设定常用的颜色集合,传入到控件中,自动生成面板颜色集合按钮,每当滑过按钮的时候,按钮边缘高亮提示当前所在颜色的按钮,当选中某个按钮时,右侧颜色条显示当前选中的颜色,此控件功能极其简单,直接采用动态生成按钮的方式,设置按钮的样式表来设置对应的颜色和高亮边框等,单击按钮发出颜色改变信号即可,对外提供该信号就行,非常适合初学者学习。
feiyangqingyun
2019/08/27
1.2K0
Qt编写自定义控件27-颜色按钮面板
PyQt5美化你的GUI界面
目录 1 圆点选择选项设置 2 选项按钮设置 3 关闭弹窗设置 4 关闭程序弹窗 5 设置关闭按钮 6 设置背景 7 下拉列表框设置 8 等待时显示进度条 ---- 1 圆点选择选项设置 效果展示 代码参考 #!/usr/bin/python # -*- coding:utf-8 -*- import sys from PyQt5 import QtWidgets, QtCore from PyQt5.QtWidgets import * class qt_view(QWidget): def
荣仔_最靓的仔
2021/09/07
3.9K0
Fdog系列(四):使用Qt框架模仿QQ实现登录界面,界面篇。
Fdog系列(三):使用腾讯云短信接口发送短信,数据库写入,部署到服务器,web收尾篇。
花狗Fdog
2021/05/06
4.2K0
Qt编写安防视频监控系统11-动态换肤
Qt中的动态换肤技术是非常一流的,直接调用qApp->setStyleSheet(qss);就可以对整个应用程序进行换肤,如果样式表内容不多,或者对应的贴图不对,效率还是蛮好的,不过据说有些人写了几千行的样式表,加载起来能够明显感觉卡顿,毕竟此时全部刷新加载重绘,是非常耗CPU的,这种情况就需要避免尽量统一样式表,能合并的就合并,当然,在性能比较好的电脑上,这个基本上遇不到的,也感觉不到的,好比现在的手机相比于十年前的手机,现在动不动都6GB内存了,比起以前256MB内存的时候,不知道爽了多少倍,软件上已经优化不了的事情,靠硬件升级到来的优化体验还是非常棒的。
feiyangqingyun
2019/08/21
1.3K0
Qt编写安防视频监控系统11-动态换肤
Qt编写数据可视化大屏界面电子看板2-配色方案
做完整个数据可视化大屏界面电子看板系统后,为了提升点逼格,需要提供好几套默认的风格样式以供选择,这样用户可以选择自己喜欢的配色方案来作为整个系统的颜色方案,去看了下市面上大部分的大屏电子看板系统,都是以蓝色为主,部分黑色,估计也许这就是大众的审美吧,那就在数据可视化大屏界面电子看板系统中也加入蓝色风格、深蓝色风格、黑色风格,三种,加上默认的紫色风格,共计内置4套风格选择,Qt的QSS是我见过的最牛逼的换肤控制样式界面颜色的东东,这个工具用好了,别提有多爽,直接qApp->setStyleSheet(qss);可以对整个应用程序换肤,如果自定义的控件定义了Q_PROPERTY的话,也会立即更改自定义控件的属性。
feiyangqingyun
2019/08/19
1.2K0
PyQt5常见布局、控件用法有哪些?
闻说社
2024/07/12
1420
PyQt5常见布局、控件用法有哪些?
相关推荐
【QT】QSS
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验