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 删除。

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
每周AI论文速递(241230-250103)
OpenAI 的 GPT-4 突破突显了通过增强推理能力来改进大语言模型的潜力。然而,大多数关于推理的研究都集中在数学任务上,而像医学这样的领域则研究较少。尽管医学领域与数学不同,但由于医疗保健的高要求,它同样需要强大的推理能力来提供可靠的答案。然而,与数学不同,验证医学推理更具挑战性。为了解决这个问题,我们提出了可验证的医学推理问题,并使用医学验证器来检查模型输出的正确性。这种可验证性通过两阶段方法促进了医学推理的发展:(1) 使用验证器指导搜索复杂的推理轨迹以微调大语言模型,(2) 应用基于验证器奖励的强化学习 (RL) 来进一步增强复杂推理。最后,我们介绍了 HuatuoGPT-o1,这是一种能够进行复杂推理的医学大语言模型,仅使用 40K 个可验证问题就超越了通用和医学专用基准模型。实验表明,复杂推理提高了医学问题解决能力,并且从强化学习中获得更大的提升。我们希望我们的方法能够激发医学和其他专业领域推理的进步。
叶子的技术碎碎念
2025/04/08
590
每周AI论文速递(241230-250103)
每周AI论文速递(250120-250124)
我们探索了一种进化搜索策略,用于扩展大语言模型中的推理计算时间。我们提出的方法,Mind Evolution,利用语言模型生成、重组和优化候选响应。该方法在解决方案评估器可用时,避免了形式化底层推理问题的需求。在控制推理成本的前提下,我们发现 Mind Evolution 在自然语言规划任务中显著优于其他推理策略,如 Best-of-N 和 Sequential Revision。在 TravelPlanner 和 Natural Plan 基准测试中,Mind Evolution 使用 Gemini 1.5 Pro 解决了超过 98% 的问题实例,且无需使用形式化求解器。
叶子的技术碎碎念
2025/04/08
890
每周AI论文速递(250120-250124)
“AI玩手机”原理揭秘:大模型驱动的移动端GUI智能体
在后LLM时代,随着大语言模型和多模态大模型技术的日益成熟,AI技术的实际应用及其社会价值愈发受到重视。AI智能体(AI Agent)技术通过集成行为规划、记忆存储、工具调用等机制,为大模型装上“手脚”,使其能够利用强大的多模态感知交互与推理决策能力,与真实世界进行有效交互,成为连接人类与数字世界的桥梁,并迎来前所未有的发展机遇。(了解更多关于智能体的见解:《在后LLM时代,关于新一代智能体的思考》) 。
澜舟科技
2024/11/22
3170
为什么 AI 能一句话操作手机和电脑?(GUI Agent 最新综述)
来自《Large Language Model-Brained GUI Agents: A Survey》综述总结
陈宇明
2025/02/26
1150
为什么 AI 能一句话操作手机和电脑?(GUI Agent 最新综述)
解密prompt系列50. RL用于优化Agent行为路径的一些思路
OpenAI新推出的Deep Research功能,属实有些惊艳,也验证了去年的一些观点,之后的大模型工作流会呈现一些截然不同的形态,有敏捷型的例如语音端到端的及时对话,也会有异步长流程的复杂任务,去做例如课题研究,信息收集,实验设计,假设验证等等。
风雨中的小七
2025/03/06
2910
解密prompt系列50. RL用于优化Agent行为路径的一些思路
CMU清华MIT引爆全球首个Agent无限流,机器人「007」加班自学停不下来!具身智能被革命
长久以来,相比于语言或者视觉模型可以在大规模的互联网数据上训练,训练机器人的策略模型需要带有动态物理交互信息的数据,而这些数据的匮乏一直是具身智能发展的最大瓶颈。
新智元
2023/11/07
4190
CMU清华MIT引爆全球首个Agent无限流,机器人「007」加班自学停不下来!具身智能被革命
AI Agent技术的最新进展与改变世界的典型项目巡礼
在学术探索的浩瀚星空中,机器人技术领域的璀璨明珠莫过于Agent技术的深入研究,这一领域历来是创新与突破的温床。回溯至大模型浪潮兴起之前,Agent技术的辉煌篇章便已悄然铺展,诸如Alphago这样的里程碑式案例,以其卓越的环境感知、精准决策与高效行动能力,生动诠释了Agent技术的闭环魅力。同时,DeepMind的Agent57在强化学习领域的游戏挑战中崭露头角,而随后问世的Gato则展现了更为广泛的适用性,乃至OpenAI在“躲猫猫”游戏中展现的多智能体协作,无不预示着Agent技术的无限潜力。
汀丶人工智能
2024/07/08
6090
AI Agent技术的最新进展与改变世界的典型项目巡礼
每日论文速递 | ReAct Meets ActRe: Agent规划自主解释
摘要:语言代理通过对基础模型进行推理,展示了自主决策能力。最近,人们开始利用多步骤推理和行动轨迹作为训练数据,努力训练语言代理以提高其性能。然而,收集这些轨迹仍然需要大量人力,要么需要人工注释,要么需要实现各种提示框架。在这项工作中,我们提出了 A
zenRRan
2024/04/11
4010
每日论文速递 | ReAct Meets ActRe: Agent规划自主解释
打通智能体「自我进化」全流程!复旦推出通用智能体平台AgentGym
LLM-based Agent,已经不再需要人类监督者的帮助,开始实现「自我进化」!
机器之心
2024/06/17
3740
每周AI论文速递(241104-241108)
当前构建 GUI 智能体的工作主要依赖于如 GPT-4o 和 GeminiProVision 等稳健的商业视觉语言模型 (VLM)。由于开源 VLM 在 GUI 接地和分布外 (OOD) 场景中与闭源 VLM 相比存在显著性能差距,实践者通常不愿使用开源 VLM。为推动该领域研究,我们开发了 OS-Atlas——一个在 GUI 接地和 OOD 智能体任务中表现卓越的基础 GUI 动作模型,这归功于数据和建模方面的创新。我们投入大量工程资源,开发了一个开源工具包,用于跨 Windows、Linux、MacOS、Android 和 Web 等多个平台合成 GUI 接地数据。利用此工具包,我们发布了迄今最大的开源跨平台 GUI 接地语料库,包含超过 1300 万个 GUI 元素。该数据集与模型训练创新相结合,为 OS-Atlas 理解 GUI 截图并泛化至未见界面提供了坚实基础。在涵盖移动设备、桌面设备和 Web 三个平台的六个基准上进行广泛评估后,OS-Atlas 显示出相较于之前最先进模型的显著性能提升。我们的评估还揭示了持续改进和扩展开源 VLM 智能体能力的宝贵见解。
叶子的技术碎碎念
2025/04/08
490
每周AI论文速递(241104-241108)
具身抓取研究综述
论文链接:https://www.mdpi.com/1424-8220/25/3/852
一点人工一点智能
2025/04/04
950
具身抓取研究综述
字节版Operator抢跑OpenAI? 直接免费开源, 网友:怒省200美元!
1 月 24 日凌晨 2 点,OpenAI 面向月供 200 美元的 ChatGPT Pro 用户发布了自家的 Computer Use 智能体:Operator。
机器之心
2025/02/03
3070
字节版Operator抢跑OpenAI? 直接免费开源, 网友:怒省200美元!
APIGen-MT:高效生成多轮人机交互Agent数据的两阶段框架
随着人工智能技术的飞速发展,AI代理(Agent)已从简单的聊天机器人发展为能够执行复杂现实任务的系统,例如管理金融交易、安排预约和处理客户服务等。然而,构建真正稳健可靠的AI代理仍面临一个关键挑战:高质量多轮交互数据的稀缺性。本文将深入解析一个创新性的解决方案——APIGen-MT框架,这是一个专为生成高质量多轮人机交互数据而设计的两阶段框架。
致Great
2025/04/11
760
APIGen-MT:高效生成多轮人机交互Agent数据的两阶段框架
手机「自动驾驶」大揭秘!vivo万字综述探讨大模型手机自动化
你是否想过,手机能像电影钢铁侠中的智能管家贾维斯那般,一句话就能顺畅自如地完成各种复杂任务。
机器之心
2025/02/03
1080
手机「自动驾驶」大揭秘!vivo万字综述探讨大模型手机自动化
纯视觉方案,精准操控电脑和手机!港大Aria-UI登顶,超越Claude 3.5
然而,如何将用户的自然语言指令精准映射(grounding)到界面元素一直是该领域的核心挑战。
新智元
2025/02/15
550
纯视觉方案,精准操控电脑和手机!港大Aria-UI登顶,超越Claude 3.5
突破数据瓶颈!交大研发电脑智能体,让 AI 替你熬夜做 PPT
本文共同第一作者为上海交通大学 ACM 班的三年级本科生何彦衡,金嘉禾,两人均为 GAIR 实验室成员,指导老师为刘鹏飞副教授。上海交通大学生成式人工智能实验室 (GAIR Lab)的主要研究方向为:大模型的复杂推理,大模型预训练中的数据工程,多模态大模型,以及智能体。实验室主页:https://plms.ai/
计算机视觉研究院
2024/12/25
1050
突破数据瓶颈!交大研发电脑智能体,让 AI 替你熬夜做 PPT
AI 工具推荐之 Agent TARS:字节跳动开源的多模态AI智能体
在人工智能技术迅猛发展的当下,字节跳动推出了一款名为Agent TARS的开源多模态AI智能体,迅速引起了业界和学术界的广泛关注。作为一款基于UI-TARS模型的创新工具,Agent TARS旨在通过自然语言指令实现对计算机的自动化控制,尤其是在图形用户界面(GUI)交互中表现出色。它的开源性质不仅降低了技术应用的门槛,还为开发者提供了广阔的定制空间,推动了AI技术在自动化、用户体验提升以及多领域融合中的发展。
AI.NET 极客圈
2025/04/11
3420
AI 工具推荐之 Agent TARS:字节跳动开源的多模态AI智能体
斯坦福多模态交互 Agent 综述:Agent AI 集成及其技术挑战
斯坦福大学李飞飞、微软研究院首席研究员等联合撰写的论文,这篇 Agent AI 综述一共80页。
AIGC新知
2025/02/07
4660
斯坦福多模态交互 Agent 综述:Agent AI 集成及其技术挑战
【愚公系列】《AI Agent技术、应用与商业》003-Al Agent 的分类方式
随着人工智能技术的不断进步,智能代理(AI Agent)在各个领域的应用愈加广泛。然而,伴随着应用场景的多样化,智能代理的分类方式也变得愈发复杂。在这篇文章中,我们将深入探讨智能代理的不同分类方式,帮助大家更好地理解这一领域的多样性和复杂性。
愚公搬代码
2025/03/12
1560
ENVISIONS:一种无需人类标注的LLM自训练框架
这篇论文提出了一个名为ENVISIONS的环境引导的神经符号自训练框架,旨在解决以下两个问题:
zenRRan
2024/07/04
2320
ENVISIONS:一种无需人类标注的LLM自训练框架
推荐阅读
相关推荐
每周AI论文速递(241230-250103)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验