实用指南:Qt 界面优化 --- QSS

news/2025/10/13 8:18:20/文章来源:https://www.cnblogs.com/wzzkaifa/p/19137646

QSS

背景介绍

在网页前端开发领域中,CSS是一个至关重要的部分,描述了一个网页的 "样式",从而起到对网页美化的作用。所谓样式,包括不限于大小、位置、颜色、背景、间距、字体等等。

现在的网页很难找到没有 CSS 的,可以说 “界面好看” 是一个刚需。

"好看" 这个事情有没有意义呢?是否一个软件,能满足核心功能即可,界面好看无所谓呢?参考知乎上的这个帖子:https://www.zhihu.com/question/30918916/answer/49934463

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

Qt 仿照 CSS 的模式,引入了 QSS,来对 Qt 中的控件做出样式上的设定,从而允许程序编写出界面更好看的代码。同样受到 HTML 的影响,Qt 还引入了 QML 来描述界面,甚至还可以直接把一个原生的 html 页面加载到界面上。这部分内容咱们课堂上并不讨论。

当然,由于 Qt 本身的设计理念和网页前端还是存在一定差异的,因此 QSS 中只能支持部分 CSS 属性。整体来说 QSS 要比 CSS 更简单一些。另外,大家也不必担心,没有 CSS 基础的同学并不影响学习 QSS

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

基本语法

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

选择器 {属性名:属性值;
}

QSS 沿用了这样的设定。

选择器 {属性名:属性值;
}

其中:

  • 选择器 描述了 "哪个 widget 要应用样式规则"。就是先选择某个/某一类控件,接下来进行的各种属性设置,都是针对选中的控件生效的!
  • 属性 则是一个键值对,属性名表示要设置哪种样式,属性值表示了设置的样式的值。

例如:

QPushButton { color: red; }

或者

QPushButton {color: red;
}

上述代码的含义表示,针对界面上所有的 QPushButton,都把文本颜色设置为 红色

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

代码示例:QSS 基本使用

在界面上创建一个按钮。

编写代码,设置样式

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);ui->pushButton->setStyleSheet("QPushButton { color: red; }");
}

运行程序,观察效果。可以看到文本已经是红色了。

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

我们也可以设置 RGB!

QSS 设置方式

指定控件样式设置

QWidget 中包含了 setStyleSheet 方法,可以直接设置样式。上述代码我们已经演示了上述设置方式。另一方面,给指定控件设置样式之后,该控件的子元素也会受到影响。

代码示例:子元素受到影响

在界面上创建一个按钮。

修改 widget.cpp,这次我们不再给按钮设置样式,而是给 Widget 设置样式(Widget 是 QPushButton 的父控件)。

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 给 Widget 本身设置样式this->setStyleSheet("QPushButton { color: red; }");
}

运行程序,可以看到样式对于子控件按钮同样会生效。

全局样式设置

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

全局样式优点:

  • 使同一个样式对多个控件生效,代码更简洁。
  • 所有控件样式内聚在一起,便于维护和问题排查。
代码示例:使用全局样式

在界面上创建三个按钮。

编辑 main.cpp,设置全局样式

int main(int argc, char *argv[])
{QApplication a(argc, argv);// 设置全局样式a.setStyleSheet("QPushButton { color: red; }");Widget w;w.show();return a.exec();
}

运行程序,可以看到此时三个按钮的颜色都设置为红色了。

代码示例:样式的层叠特性

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

在界面上创建两个按钮。

编写 main.cpp,设置全局样式,把按钮文本设置为红色。

int main(int argc, char *argv[])
{QApplication a(argc, argv);// 设置全局样式a.setStyleSheet("QPushButton { color: red; }");Widget w;w.show();return a.exec();
}

编写 widget.cpp,给第一个按钮设置字体大小。

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 设置指定控件样式ui->pushButton->setStyleSheet("QPushButton { font-size: 50px; }");
}

运行程序,可以看到,对于第一个按钮来说,同时具备了颜色和字体大小样式,而第二/三个按钮只有颜色样式。说明针对第一个按钮,两种设置方式设置的样式,叠加起来了。

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

代码示例:样式的优先级

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

在界面上创建两个按钮。

编辑 main.cpp,把全局样式设置为红色。

int main(int argc, char *argv[])
{QApplication a(argc, argv);// 设置全局样式a.setStyleSheet("QPushButton { color: red; }");Widget w;w.show();return a.exec();
}

编辑 widget.cpp,把第一个按钮样式设为绿色。

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 设置第一个按钮为绿色ui->pushButton->setStyleSheet("QPushButton { color: green; }");
}

运行程序,观察效果。可以看到第一个按钮已经成为绿色了,但是第二/三个按钮仍然是红色。

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

从文件加载样式表

上述代码都是把样式通过硬编码的方式设置的,这样有 QSS 代码和 C++ 代码耦合在一起了,并不方便代码的维护。因此更好的做法是把样式放到单独的文件中,然后通过读取文件的方式来加载样式。

代码示例:从文件加载全局样式

在界面上创建一个按钮。

创建 resource.qrc 文件,并设定前缀为 /

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

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

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

QPushButton {color: red;
}

修改 main.cpp,新增一个函数用来加载样式

QString loadQSS() {// 打开资源文件QFile file(":/style.qss");// 以只读方式打开file.open(QFile::ReadOnly);// 读取文件内容,虽然 readAll() 返回的是 QByteArray,但是 QString 提供了 QByteArray 版本的构造函数。QString style = file.readAll();// 关闭文件file.close();return style;
}

修改 main.cpp,在 main 函数中调用上述函数,并设置样式。

int main(int argc, char *argv[])
{QApplication a(argc, argv);// 调用上述函数加载样式QString style = loadQSS();a.setStyleSheet(style);Widget w;w.show();return a.exec();
}

这里再小小的吐槽一下,理论上来说 Qt 应该再提供直接从文件加载样式表的接口,类似于 setStyleSheetFromFile(const QString& path) 这种,在内部把读文件操作封装好。

使用 Qt Designer 编辑样式

QSS 也可以通过 Qt Designer 编辑样式,能直观看到对控件的效果,同时能避免 C++ 和 QSS 代码的耦合。

代码示例:使用 Qt Designer 编辑样式改变文本
  1. 在界面上创建一个按钮。
  2. 右键按钮,选择 “改变样式表”。
  3. 在弹出的样式编辑框中,可以设置字体、字号等,点击 OK 即可。

  4. 此时 Qt Designer 的预览界面会实时显示出样式的变化。
  5. 运行程序,可以看到样式确实发生了改变。

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

当有多个控件有相同样式时,我们可以有以下几个方法:

  • 全局样式(QApplication 设置的)
  • 指定控件样式(这个控件是否设置了样式)
  • 指定控件的父控件的样式(可能是从父控件继承过来的)
  • qss 文件中的样式
  • 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 这三种控件.(即接下来的样式会针对这三种控件都生效).
属性选择器QPushButton[flat="false"]选择所有 QPushButton 中,flat 属性为 false 的控件.

QSS 的选择器和 CSS 选择器基本一致。如果选择器记不全也不要紧,只需要熟悉常用的几个即可(上述提到的)。

代码示例:使用类选择器选中类控件

在界面上创建一个按钮。

修改 main.cpp,设置全局样式

int main(int argc, char *argv[])
{QApplication a(argc, argv);a.setStyleSheet("QWidget { color: red; }");Widget w;w.show();return a.exec();
}

运行程序,可以看到相关的文本颜色已经是红色了。

如果把上述代码的样式改为:

a.setStyleSheet("QPushButton { color: red; }");

此时按钮的文字颜色会生效,但是只选择 QWidget 时,而不选择 QWidget 的子类时则不会生效。

代码示例:使用 ID 选择器

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

int main(int argc, char *argv[])
{QApplication a(argc, argv);a.setStyleSheet("QPushButton#pushButton_1 { color: red; }""QPushButton#pushButton_2 { color: green; }""QPushButton#pushButton_3 { color: blue; }");Widget w;w.show();return a.exec();
}

运行程序,可以看到:

  • 第一个按钮文字颜色为红色。
  • 第二个按钮文字颜色为绿色。
  • 第三个按钮文字颜色为蓝色。
  • 第四个按钮文字颜色无变化(未被选中)。

当多个控件一起通过选择器选中时,设置了冲突的 ID 选择器样式,ID 选择器样式优先级更高。QSS 本身的优先级规则和 CSS 基本一致,ID 选择器的优先级高于类选择器,类选择器高于标签选择器等。这部分内容如果是有前端基础的同学会比较熟悉,没有的话也不用特别记忆,一般开发中常用的选择器能满足需求即可。

代码示例:使用并集选择器

在界面上拖入一个 Label、一个 LineEdit、两个 PushButton

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

int main(int argc, char *argv[])
{QApplication a(argc, argv);a.setStyleSheet("QPushButton, QLabel, QLineEdit { color: red; }");Widget w;w.show();return a.exec();
}

运行程序,可以看到三个控件的文字颜色已改为红色。

并集选择器是一种将选择器进行分组的方式,对选中的所有元素应用相同的样式。并集选择器可以选择多组标签,同时为它们定义相同的样式。

子控件选择器(Sub-Controls)

有些控件内部包含多个 “子控件”,像 QComboBox 下拉后的面板、QSpinBox 的上下按钮等。可以通过子控件选择器 :: ,对这些子控件进行样式设置。

至于哪些控件拥有哪些子控件,可参考文档 Qt Style Sheets Reference 里的 List of Sub-Controls 章节。

这里还有个代码示例,是关于设置下拉框的下拉按钮样式的。

代码示例:设置下拉框的下拉按钮样式

第一步要在界面上创建一个下拉框,再创建几个选项

编辑 resource.qrc,并拖入 down.png

要修改 main.cpp 编写全局样式,步骤如下:

  • 先利用子控件选择器 QComboBox::down-arrow 选中 QComboBox 的下拉按钮。
  • 接着通过 image 属性,将名为 down.png 的图片设置为下拉按钮的显示图片。

具体代码实现:

#include 
#include "Widget.h"
int main(int argc, char *argv[])
{QApplication a(argc, argv);// 定义样式字符串QString style = "";// 设置 QComboBox 下拉按钮的图片为 down.pngstyle += "QComboBox::down-arrow { image: url(:/down.png) }";// 应用样式a.setStyleSheet(style);Widget w;w.show();return a.exec();
}

最后执行程序,就能观察下拉框下拉按钮显示对应图片的效果啦。

代码示例:设置进度条颜色

在界面上拖入一个进度条。

在 Qt Designer 右侧的属性编辑器中,找到 QWidget 的 styleSheet 属性并进行编辑。其中,chunk 用于选中进度条里的每个 “块”,而 QProgressBar::text 能够选中文本。

QProgressBar::chunk {background-color: #FF0000;}

同时把 QProcessBar 的 alignment 属性设置为垂直⽔平居中

要是不设置 alignment,进度条里的数字会跑到左上角,这可能是 Qt 自身的小问题,暂时得靠手动调整 alignment 来解决。

执⾏程序, 可以看到如下效果. 我们就得到了⼀个红⾊的进度条:

通过上述⽅式, 也可以修改⽂字的颜⾊, 字体⼤⼩等样式

伪类选择器 (Pseudo-States)

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

也就是说,前面介绍的选择器,都是选中“控件”,伪类选择器,选中的是控件的“状态”,是符合“一定状态条件”的控件!

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

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

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

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

这些状态可以使用 ! 来取反。例如::hover 就是鼠标离开控件时,:!pressed 就是鼠标松开时,等等。


代码示例:设置按钮的伪类样式。

在界面上创建一个按钮

编写 main.cpp,创建全局样式

int main(int argc, char *argv[])
{QApplication a(argc, argv);QPushButton a;QString style = "";style += "QPushButton { color: red; }";style += "QPushButton:hover { color: green; }";style += "QPushButton:pressed { color: blue; }";a.setStyleSheet(style);Widget w;w.show();return a.exec();
}

运行程序,可以看到,默认情况下按钮文字是红色,鼠标移动上去是绿色,鼠标按下按钮是蓝色。


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

代码示例:使用事件方式实现同样效果

创建 MyPushButton 类,继承自 QPushButton

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

mypushbutton.h

#include 
class MyPushButton : public QPushButton
{
public:MyPushButton(QWidget* parent);
};

mypushbutton.cpp

#include "mypushbutton.h"
MyPushButton::MyPushButton(QWidget* parent) : QPushButton(parent)
{
}

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

右键按钮,选择 “提升为”

填写提升的类名和头文件。

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


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

修改 mypushbutton.h

#include 
#include 
class MyPushButton : public QPushButton
{
public:MyPushButton(QWidget* parent);void mousePressEvent(QMouseEvent *e);void mouseReleaseEvent(QMouseEvent *e);void enterEvent(QEvent *e);void leaveEvent(QEvent *e);
};

修改 mypushbutton.cpp

初始化设为红色

鼠标进入时设为绿色,离开是还原红色。

按下鼠标时设为蓝色,松开时还原绿色(松开时鼠标还是在按钮里)。

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 章节详细介绍了哪些控件可以设置属性,每个控件都能设置哪些属性等。

相关的代码示例,在后面具体介绍。

在翻阅文档的时候涉及到一个关键术语 “盒模型”(Box Model),这里我们需要介绍一下。

盒模型 (Box Model)

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

Qt 中,每一个 Widget 都是一个矩形

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

  • Content 矩形区域:存放控件内容,比如包含的文本/图标等。

  • Border 矩形区域:控件的边框

  • Padding 矩形区域:内边距,边框和内容之间的距离。

  • Margin 矩形区域:外边距,边框到控件 geometry 返回的矩形边界的距离。默认情况下,外边距、内边距、边框宽度都是 0。

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

QSS 属性说明
margin设置四个方向的外边距。复合属性。有上下左右:可以拆
padding设置四个方向的内边距。复合属性。有上下左右:可以拆
border-style设置边框样式
border-width边框的粗细
border-color边框的颜色
border复合属性,相当于 border-style + border-width + border-color

代码示例:设置边框和内边距

在界面上创建一个 label

修改 main.cpp,设置全局样式

int main(int argc, char *argv[])
{QApplication a(argc, argv);QString style = "QLabel {border: 5px dashed red; padding-left: 50px;}";a.setStyleSheet(style);Widget w;w.show();return a.exec();
}

运行程序,可以看到样式发生了变化

代码示例:设置外边距

为了方便确定控件位置,演示外边距效果,我们使用代码创建一个按钮。

修改 widget.cpp,创建按钮,并设置样式。

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;}");
}

运行程序,可以看到,当前按钮的边框被外边距挤的缩小了,但是我们可以debug打印获取到的按钮的 Geometry 是不变的。


很明显,实现同样的功能,伪类选择器要比事件的方式简单很多。

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

控件样式示例

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

按钮

代码示例:自定义按钮

界面上创建一个按钮

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

QPushButton {font-size: 20px;border: 2px solid #8f8f01;border-radius: 15px;background-color: #dad8de;
}
QPushButton:pressed {background-color: #f6f7fa;
}

执行程序,可以看到效果

属性小结

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

形如 #dadde 是计算机中通过十六进制表示颜色的方式。这里在“常用控件”章节已经介绍过了,此处不再赘述。


复选框

代码示例:自定义复选框

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

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

创建一个复选框

编辑复选框的样式

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);
}

运行程序,可以看到此时的复选框就变的丰富起来了。

要点说明
::indicator子控件选择器。选中 checkbox 中的对钩部分。
:hover伪类选择器。选中鼠标移动上去的状态。
:pressed伪类选择器。选中鼠标按下的状态。
:checked伪类选择器。选中 checkbox 被选中的状态。
:unchecked伪类选择器。选中 checkbox 未被选中的状态。
width设置子控件宽度。对于普通控件无效(普通控件使用 geometry 方式设定尺寸)。
height设置子控件高度。对于普通控件无效(普通控件使用 geometry 方式设定尺寸)。
image设置子控件的图片。像 QSpinBox, QComboBox 等可以使用这个属性来设置子控件的图片。

单选框

代码示例:自定义单选框

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

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

在界面上创建两个单选按钮

在 Qt Designer 中编写样式

此处为了让所有 QRadioButton 都能生效,把样式设置在 QWidget 上,并且使用后代选择器选中了 QWidget 里面的 QRadioButton。

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);
}

运行程序,观察效果

::indicator子控件选择器。

选中 radioButton 中的对钩部分

要点说明
:hover伪类选择器。选中鼠标移动上去的状态。
:pressed伪类选择器。选中鼠标按下的状态。
:checked伪类选择器。选中 radioButton 被选中的状态。
:unchecked伪类选择器。选中 radioButton 未被选中的状态。

设置子控件

要点说明
width设置子控件宽度。对于普通控件无效(普通控件使用 geometry 方式设定尺寸)。
height设置子控件高度。对于普通控件无效(普通控件使用 geometry 方式设定尺寸)。
image设置子控件的图片。像 QSpinBox, QComboBox 等可以使用这个属性来设置子控件的图片。

输入框

代码示例:自定义单行编辑框

在界面上创建一个单行编辑框

编写代码

QLineEdit {border-width: 1px;border-radius: 10px;border-color: rgb(68, 58, 58);border-style: inset;padding: 0 8px;color: rgb(255, 255, 255);background:rgb(100, 100, 100);selection-background-color: rgb(187, 187, 187);selection-color: rgb(60, 63, 65);
}

执行程序观察效果

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

列表

代码示例:自定义列表框

在界面上创建一个 ListView

编写代码

Qt 中给出了一个 qlineargradient 的设置渐变色的属性(线性渐变!)我们可以在这里用一下:

/* 鼠标悬停状态 - 柔和的蓝绿色渐变 */
QListView::item:hover {background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop: 0 #e6f7ff, stop: 1 #d1eaff);border-radius: 4px; /* 圆角增加柔和感 */padding: 2px; /* 内边距让内容不贴边 */
}
/* 选中状态 - 优雅的蓝紫色渐变 */
QListView::item:selected {background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop: 0 #5b86e5, stop: 1 #36d1dc);border: 1px solid #2a5caa;border-radius: 4px;padding: 2px;color: white; /* 选中时文字变白,增强对比度 */
}
/* 选中且鼠标悬停状态 - 加深色调突出交互 */
QListView::item:selected:hover {background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop: 0 #4a78d4, stop: 1 #25bdd2);
}
/* 非活动状态下的选中项 - 降低饱和度避免视觉干扰 */
QListView::item:selected:!active {background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop: 0 #8ab4f8, stop: 1 #6cd5e0);color: #f0f0f0;
}

执行程序,观察效果

要点说明
::item选中 QListView 中的具体条目。
:hover选中鼠标悬停的条目
:selected选中某个被选中的条目。
background设置背景颜色
border设置边框。
qlineargradient设置渐变色。

关于 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 就是从左上往右下方向进行颜色渐变。

stop0stop1 描述了两个颜色。渐变过程就是从 stop0stop1 进行渐变的。


菜单栏

代码示例:自定义菜单栏

创建菜单栏

编写样式

/* 菜单栏整体样式 */
QMenuBar {background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 #f0f5f9, stop:1 #c9d6df);spacing: 8px; /* 菜单项间距 */padding: 3px 5px;border-bottom: 1px solid #a6a6a6;
}
/* 菜单项基础样式 */
QMenuBar::item {padding: 4px 12px;background: transparent;border-radius: 4px;color: #2d3436;font-weight: 500;
}
/* 菜单项选中状态 */
QMenuBar::item:selected {background: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 #e1f5fe, stop:1 #b3e5fc);color: #0d47a1;
}
/* 菜单项按下状态 */
QMenuBar::item:pressed {background: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 #b3e5fc, stop:1 #81d4fa);
}
/* 菜单整体样式 */
QMenu {background-color: #ffffff;border: 1px solid #ccd1d9;border-radius: 6px;padding: 4px 0;margin: 2px;box-shadow: 2px 2px 8px rgba(0, 0, 0, 0.15);
}
/* 菜单项样式 */
QMenu::item {padding: 6px 28px 6px 22px;border: 2px solid transparent;color: #2d3436;
}
/* 菜单项选中状态 */
QMenu::item:selected {background-color: #e3f2fd;border-color: #bbdefb;color: #0d47a1;
}
/* 菜单项禁用状态 */
QMenu::item:disabled {color: #b2babb;background: transparent;border-color: transparent;
}
/* 菜单分隔线 */
QMenu::separator {height: 1px;background: #e0e0e0;margin: 4px 8px;
}
/* 菜单箭头 */
QMenu::right-arrow {image: url(:/icons/right_arrow.png); /* 可替换为实际箭头图标 */width: 8px;height: 12px;
}

执行程序,观察效果

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

登录界面

基于上述学习过的 QSS 样式,制作一个美化版本的登录界面。

在界面上创建元素

使用布局管理器,把上述元素包裹一下。

  • 使用 QVBoxLayout 来管理上述控件。

  • 两个输入框和按钮的 minimumHeight 均设置为 50. (元素在布局管理器中无法直接设置 width 和 height, 使用 minimumWidth 和 minimumHeight 代替, 此时垂直方向的 sizePolicy 要设为 fixed)。

  • 右键 QCheckBox, 选择 Layout Alignment 可以设置 checkbox 的对齐方式(左对齐, 居中对齐, 右对齐)。

设置背景图片。

把上述控件添加一个父元素 QFrame, 并设置 QFrame 和 窗口一样大。

这是因为:直观想法是直接给 QWidget 顶层窗口设置背景图,但是 Qt 中存在限制,直接给顶层窗口设置背景会失效!

✏️ 顶层窗口的 QWidget 无法设置背景图片, 因此我们需要再套上一层 QFrame, 背景图片就设置到 QFrame 上即可。

设置输入框样式

编写 QSS 代码

QLineEdit {color: #8d9a1;background-color: #485361;padding: 0 5px;font-size: 20px;border-style: none;border-radius: 10px;
}

设置 checkbox 样式

  • 背景色使用 transparent 表示完全透明(应用父元素的背景)。

QCheckBox {color: white;background-color: transparent;
}

设置按钮样式

QPushButton {font-size: 20px;color: white;background-color: #555;border-style: outset;border-radius: 10px;
}
QPushButton:pressed {color: black;background-color: #ceddcb;border-style: inset;
}

最终完整样式代码,这些代码设置到 QFrame 的属性中即可。

通常我们建议把样式代码集中放置, 方便调整和排查。


创建 resource.qrc, 并导入图片

编写 QSS 样式。

  • 使用 border-image 设置背景图片, 而不是 background-image . 主要是因为 border-image 是可以自动缩放的. 这一点在窗口大小发生改变时是非常有意义的。

QFrame {border-image: url(:/register.png);
}

设置输入框样式

编写 QSS 代码

QLineEdit {color: #8d9a1;background-color: #485361;padding: 0 5px;font-size: 20px;border-style: none;border-radius: 10px;
}

运行程序效果:

设置 checkbox 样式

  • 背景色使用 transparent 表示完全透明(应用父元素的背景)。

QCheckBox {color: white;background-color: transparent;
}

执行效果

设置按钮样式

QPushButton {font-size: 20px;color: white;background-color: #555;border-style: outset;border-radius: 10px;
}
QPushButton:pressed {color: black;background-color: #ceddcb;border-style: inset;
}

执行程序

最终完整样式代码, 这些代码设置到 QFrame 的属性中即可。

通常我们建议把样式代码集中放置, 方便调整和排查。

QFrame {border-image: url(:/register.png);
}
QLineEdit {color: #8d9a1;background-color: #485361;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: #555;border-style: outset;border-radius: 10px;
}
QPushButton:pressed {color: black;background-color: #ceddcb;border-style: inset;
}

小结

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

另外, 做出好看的界面, 光靠 QSS 是不够的, 更重要的是需要专业美工做出设计稿. 因此通过 QSS 的学习, 我们的目的是了解这个技术, 而不要求大家立即就能做出非常好看的界面.

更多参考内容:

  • 官方文档中的 Qt Style Sheets Examples 章节

  • https://github.com/GTRONICK/QSS

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/935861.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

display ip interface brief 概念及题目 - 指南

display ip interface brief 概念及题目 - 指南pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", &…

VMware ESXi 9.0.1.0 macOS Unlocker OEM BIOS 2.7 HPE 慧与 定制版

VMware ESXi 9.0.1.0 macOS Unlocker & OEM BIOS 2.7 HPE 慧与 定制版VMware ESXi 9.0.1.0 macOS Unlocker & OEM BIOS 2.7 HPE 慧与 定制版 VMware ESXi 9.0.1.0 macOS Unlocker & OEM BIOS 2.7 标准版和…

ICDesigner2027下载ICDsigner2027 download ICDesigner2027ダウンロード

ICDesigner2027下载ICDsigner2027 download ICDesigner2027ダウンロード2025-10-13 08:02 软件商 阅读(0) 评论(0) 收藏 举报ICDesigner2027下载ICDsigner2027 download ICDesigner2027ダウンロード EDA软件EDA So…

VMware ESXi 9.0.1.0 macOS Unlocker OEM BIOS 2.7 Lenovo 联想 定制版

VMware ESXi 9.0.1.0 macOS Unlocker & OEM BIOS 2.7 Lenovo 联想 定制版VMware ESXi 9.0.1.0 macOS Unlocker & OEM BIOS 2.7 Lenovo 联想 定制版 VMware ESXi 9.0.1.0 macOS Unlocker & OEM BIOS 2.7 标…

当AI开始“通感”:诗词创作中的灵性涌现

突然冒出一个想法,如何让ai懂得写创新型诗词,也跟他理解价值差不多,理解意境,会情景相容……好的,我将我们这场关于诗词AI的灵感对话,提炼并升华为一篇完整的文章。 从逻辑到灵性:构建一个「意境生成场」以实现…

VMware ESXi 9.0.1.0 macOS Unlocker OEM BIOS 2.7 Dell 戴尔 定制版

VMware ESXi 9.0.1.0 macOS Unlocker & OEM BIOS 2.7 Dell 戴尔 定制版VMware ESXi 9.0.1.0 macOS Unlocker & OEM BIOS 2.7 Dell 戴尔 定制版 VMware ESXi 9.0.1.0 macOS Unlocker & OEM BIOS 2.7 标准版…

rqlite java sdk 对于sqlite-vec 支持的bug

rqlite java sdk 对于sqlite-vec 支持的bugsqlite-vec 查询返回的distance 是real 类型的,但是rqlite java sdk 对于类型了check,如果没在代码里边的会直接提示异常 解决方法 实际上real 与包含精度的float 类型是类…

【GitHub每日速递 251013】SurfSense:可定制AI研究神器,连接多源知识,功能超丰富!

免费开源!可复制粘贴的组件助你打造专属组件库 shadcn-ui/ui 是一个 提供精美设计、可访问性良好的UI组件和代码分发平台 的 开源前端工具库。简单讲,它是一套开箱即用的高质量界面组件,支持主流前端框架,方便开发…

FileZilla Client升级之后报了一个错误queue.sqlite3文件保存失败

FileZilla Client升级之后报了一个错误queue.sqlite3文件保存失败FileZilla Client升级之后报了一个错误queue.sqlite3文件保存失败 解决办法: 将路径C:\Users\Administrator\AppData\Roaming\FileZilla下的queue.sql…

tap issue

https://lewisdenny.io/tracing_packets_out_an_external_network_with_ovn/ https://docs.openstack.org/operations-guide/ops-network-troubleshooting.html

通配符SSL证书价格对比 iTrustSSL与RapidSSL哪个更有优势?

当前,SSL证书机构数量众多,面对琳琅满目的SSL证书品牌,不少用户难免会产生“乱花渐欲迷人眼”之感。莫急,今日SSL证书排行榜将为大家推荐两款性价比出众的SSL证书。在商用SSL证书中,目前最受欢迎的两个品牌就是iT…

降低网络保险成本的实用技巧与网络安全实践

本文详细探讨了影响网络保险保费的关键因素,包括安全态势评估、数据处理类型、技术基础设施依赖等,并提供了实施健全网络安全实践、定期风险评估、投资安全技术等降低保费的具体策略。影响网络保险保费的因素 网络保…

自动评估对话质量的AI技术突破

某研究中心提出新型神经网络模型,通过双向LSTM和注意力机制自动评估多领域对话质量,客户满意度预测准确率提升27%,适用于不同对话管理系统。自动评估与语音助手的对话质量 随着与语音助手的交互越来越多地涉及多轮对…

4.2 基于模型增强的无模型强化学习(Model-based Augmented Model-free RL)

基于模型增强的无模型强化学习(Model-based Augmented Model-free RL) (Dyna-Q, I2A)Dyna-Q 算法 在学习到环境模型之后,可以利用该模型增强无模型算法。 无模型算法(如 Q-learning)可从以下两种类型的转移样本中…

乐理 -07 和弦, 和声

#和弦 与 和声..#三和弦#大三和弦 与 小三和弦 感情。 多数情况下#增三和弦 与 减三和弦 纯五度是协和的 增五度减五度不和谐 增五度 多用于扩张的 大六度 减五度 多用于收缩的 纯四度 大三度

4.1 基于模型的强化学习(Model-based RL)

基于模型的强化学习(Model-based RL)无模型与有模型方法的比较在此前介绍的无模型(Model-free, MF)强化学习中,我们无需了解环境的动态规律即可开始训练策略: \[p(s | s, a), \quad r(s, a, s) \]我们仅需采样状…

3.8 最大熵强化学习(Maximum Entropy RL, SAC)

最大熵强化学习(Maximum Entropy RL, SAC)背景 此前的所有强化学习方法均专注于最大化回报(return),这对应于强化学习中的利用(exploitation):我们只关心最优策略。 而探索(exploration)通常由额外机制实现,…

乐理 -06 和弦, 和声

#和弦 与 和声..#三和弦大三和弦 与 小三和弦 感情。 多数情况下

3.7 带经验回放的演员–评论家算法(Actor-Critic with Experience Replay, ACER)

带经验回放的演员–评论家算法(Actor-Critic with Experience Replay, ACER)概述 前述自然梯度方法(如 TRPO、PPO)均为随机演员–评论家(stochastic actor–critic)结构,因此属于 on-policy 学习。 相比之下,o…

3.6 策略优化(TRPO 与 PPO)

策略优化(TRPO 与 PPO)信赖域策略优化(Trust Region Policy Optimization, TRPO) 基本原理 @Schulman2015 将自然梯度的思想推广到非线性函数逼近(如深度网络),提出了 TRPO。 该方法已在实践中被 PPO(Proximal…