文章目录
-
- 一、控件概述
-
- [1.1 什么是Qt控件?](#1.1 什么是Qt控件?)
- [1.2 控件体系的发展历程](#1.2 控件体系的发展历程)
- 二、QWidget核心属性
-
- [2.1 核心属性概览](#2.1 核心属性概览)
- [2.2 常用属性实战代码](#2.2 常用属性实战代码)
-
- [2.2.1 enabled(控件启用/禁用)](#2.2.1 enabled(控件启用/禁用))
- [2.2.2 geometry(位置和尺寸)](#2.2.2 geometry(位置和尺寸))
- [2.2.3 windowTitle(窗口标题)](#2.2.3 windowTitle(窗口标题))
- [2.2.4 windowIcon(窗口图标)](#2.2.4 windowIcon(窗口图标))
- [2.2.5 windowOpacity(透明度)](#2.2.5 windowOpacity(透明度))
- [2.2.6 cursor(鼠标光标)](#2.2.6 cursor(鼠标光标))
- [2.2.7 font(字体设置)](#2.2.7 font(字体设置))
- [2.2.8 toolTip (提示说明)](#2.2.8 toolTip (提示说明))
- [2.2.9 toolTip (提示说明)](#2.2.9 toolTip (提示说明))
- [三、QSS 界面设计](#三、QSS 界面设计)
-
- 常用样式属性
- QSS中颜色的表示
-
- [1. 纯色背景(最常用)](#1. 纯色背景(最常用))
- [2. 文字颜色(前景色)](#2. 文字颜色(前景色))
- [1. 渐变背景](#1. 渐变背景)
- [2. 背景图+颜色叠加](#2. 背景图+颜色叠加)
- 通过Designer修改QSS
- 通过代码修改QSS
一、控件概述
1.1 什么是Qt控件?
Widget(译为"控件")是 Qt 图形化界面的基本构成要素,像按钮、列表视图、树形视图、输入框、滚动条、下拉框等,都属于 Qt 控件。Qt 不仅提供了大量开箱即用的内置控件(可在 Qt Designer 中直接选用),还支持自定义控件扩展------当内置控件无法满足需求时,开发者可通过扩展现有控件或从零开发新控件实现个性化功能。
1.2 控件体系的发展历程
控件是 GUI 开发的通用概念,其发展经历了三个阶段:
- 第一阶段:无控件时代。需通过绘图 API 手动绘制按钮、输入框等,代码繁琐(如文曲星 Lava 平台开发)。
- 第二阶段:粗略控件阶段。仅提供按钮、输入框、单选框等最基础控件(如 HTML 原生控件)。
- 第三阶段:完整控件体系。覆盖大部分 GUI 开发场景,代表框架包括 Qt、MFC、VB、Android SDK、Element-UI 等(前端 Element-UI 控件在丰富度和美观度上更具优势)。
二、QWidget核心属性
在 Qt 中,所有控件均继承自 QWidget 类,QWidget 包含了控件体系的通用属性,这些属性可通过 Qt Designer 可视化修改,也可通过代码动态调整**(属性详情可在 Qt Assistant 中搜索 QWidget 查看,或在 Qt Creator 中选中 QWidget 按 F1 查看文档)**。
2.1 核心属性概览
| 属性 | 作用 |
|---|---|
| enabled | 设置控件是否可使用(false 表示禁用,禁用后控件灰色且不响应输入) |
| geometry | 位置和尺寸(含 x、y、width、height,坐标以父元素左上角为原点) |
| windowTitle | 设置顶层控件(独立窗口)的标题(子控件设置无效) |
| windowIcon | 设置顶层控件的图标(子控件设置无效) |
| windowOpacity | 控件透明度(取值 0.0~1.0,0.0 全透明,1.0 完全不透明) |
| cursor | 鼠标悬停时的图标形状(如箭头、沙漏、十字等) |
| font | 字体属性(含字体家族、大小、粗体、斜体、下划线等) |
| toolTip | 鼠标悬停时状态栏显示的提示信息 |
| statusTip | 控件状态改变时(如按钮被按下)显示的提示信息 |
| whatsThis | 鼠标悬停并按下 Alt+F1 时弹出的帮助信息 |
| styleSheet | 用 CSS 语法设置控件样式(Qt 支持的样式子集称为 QSS,对前端开发者友好) |
| focusPolicy | 控件获取焦点的策略(如 Tab 键选中、鼠标点击选中等) |
| contextMenuPolicy | 上下文菜单显示策略(如禁用菜单、自定义菜单等) |
| locale | 设置语言和国家地区 |
| acceptDrops | 是否接受拖放操作(true 可接收拖放事件) |
| minimumSize / maximumSize | 控件的最小/最大尺寸限制 |
| sizePolicy | 布局管理器中的缩放方式 |
| windowModality | 窗口模态行为(是否阻塞其他窗口交互) |
| sizeIncrement | 拖动窗口时的尺寸增量单位 |
| baseSize | 窗口基础大小,配合 sizeIncrement 计算调整后的尺寸 |
| palette | 调色板,设置控件颜色风格 |
| mouseTracking | 是否跟踪鼠标移动事件(true 时鼠标划过持续触发移动事件) |
| tabletTracking | 跟踪触摸屏移动事件(Qt 5.9 新增,类似 mouseTracking) |
| layoutDirection | 布局方向(左到右、右到左或跟随全局) |
| autoFillBackground | 是否自动填充背景颜色 |
| windowFilePath | 关联本地文件路径(实际作用有限) |
| accessibleName / accessibleDescription | 无障碍访问名称/描述(供屏幕阅读器等辅助技术使用) |
| inputMethodHints | 输入框合法数据格式提示(如仅允许输入数字、日期) |
2.2 常用属性实战代码
2.2.1 enabled(控件启用/禁用)
- 核心 API:
isEnabled()(获取启用状态)、setEnabled(bool)(设置启用状态) - 代码示例1:创建禁用状态的按钮
cpp
Widget::Widget(QWidget *parent)
: QWidget(parent), ui(new Ui::Widget)
{
ui->setupUi(this);
QPushButton* btn = new QPushButton(this);
btn->setText("这是个被禁用的按钮");
btn->setEnabled(false); // 禁用按钮
}
- 代码示例2:通过按钮切换另一个按钮的启用状态
- 在 Qt Designer 拖放两个按钮,objectName 分别为 pushButton 和 pushButton_2;
- 编写槽函数:
cpp
void Widget::on_pushButton_clicked()
{
qDebug()<<"执行了槽函数";
}
void Widget::on_pushButton_2_clicked()
{
bool btn1_enable=ui->pushButton->isEnabled();
if(btn1_enable) ui->pushButton_2->setEnabled(false);
else ui->pushButton_2->setEnabled(true);
}
2.2.2 geometry(位置和尺寸)
-
核心 API:
geometry()(获取位置尺寸,返回 QRect)、setGeometry(QRect)/setGeometry(int x, int y, int width, int height)(设置位置尺寸) -
QRect 表示一个以整数为单位的矩形,包含以下信息:
-
左上角坐标(x, y)
-
宽度(width)
-
高度(height)
-
Qt 还提供了浮点矩形类 QRectF。
-
-
Qt 坐标系:左手坐标系,父元素左上角为原点,X 轴向右递增,Y 轴向下递增。
-
代码示例1:控制按钮移动(上下左右方向)
- 拖放 5 个按钮,objectName 分别为 pushButton_target(目标按钮)、pushButton_up/down/left/right(方向按钮);
- 编写方向按钮槽函数:
cpp
// 向上移动
void Widget::on_pushButton_up_clicked()
{
QRect rect = ui->pushButton_target->geometry();
ui->pushButton_target->setGeometry(rect.x(), rect.y() - 5, rect.width(), rect.height());
}
// 向下移动
void Widget::on_pushButton_down_clicked()
{
QRect rect = ui->pushButton_target->geometry();
ui->pushButton_target->setGeometry(rect.x(), rect.y() + 5, rect.width(), rect.height());
}
// 向左移动
void Widget::on_pushButton_left_clicked()
{
QRect rect = ui->pushButton_target->geometry();
ui->pushButton_target->setGeometry(rect.x() - 5, rect.y(), rect.width(), rect.height());
}
// 向右移动
void Widget::on_pushButton_right_clicked()
{
QRect rect = ui->pushButton_target->geometry();
ui->pushButton_target->setGeometry(rect.x() + 5, rect.y(), rect.width(), rect.height());
}
- 代码示例2:拒绝按钮自动躲避鼠标
- 拖放两个按钮(pushButton_accept/accept_reject)和一个 Label;
- 编写槽函数:
cpp
// 接受按钮
void Widget::on_pushButton_accept_clicked()
{
ui->label->setText("Accepct");
}
// 拒绝按钮(鼠标按下时随机移动)
void Widget::on_pushButton_reject_pressed()
{
int width = this->geometry().width();
int height = this->geometry().height();
int x = rand() % width;
int y = rand() % height;
ui->pushButton_reject->move(x, y);
}
window frame 是顶层窗口(带标题栏、最小化/最大化/关闭按钮)的边框及标题栏区域,会影响控件位置和尺寸计算,非顶层 widget(如按钮、输入框等子控件)无 window frame,相关计算无差异。
- 尺寸与坐标计算分两类:包含 window frame(含边框+标题栏)和不包含 window frame(仅客户区)。
- 仅顶层 widget 有 window frame,子 widget(如按钮、标签)无,其各类尺寸/坐标 API 结果一致。
构造函数中 widget 未加入对象树,无 window frame,此时 geometry 和 frameGeometry 结果相同;运行后(如用户点击按钮时)对象树构建完成,frame 生效,两者结果出现差异。
-
包含 window frame 的 API(计算时含边框+标题栏)
- x()/y():获取横坐标/纵坐标
- pos():返回含 frame 的坐标(QPoint 对象)
- frameSize():返回含 frame 的尺寸(QSize 对象)
- frameGeometry():返回含 frame 的位置+尺寸(QRect 对象)
-
不包含 window frame 的 API(仅计算客户区)
- width()/height():获取客户区宽度/高度
- size():返回客户区尺寸(QSize 对象)
- rect():返回客户区位置+尺寸(QRect 对象)
- geometry()/setGeometry():获取/设置客户区位置+尺寸(QRect 对象)
2.2.3 windowTitle(窗口标题)
- 核心 API:
windowTitle()(获取标题)、setWindowTitle(const QString& title)(设置标题) - 代码示例:
cpp
Widget::Widget(QWidget *parent)
: QWidget(parent), ui(new Ui::Widget)
{
ui->setupUi(this);
this->setWindowTitle("这是标题"); // 设置顶层窗口标题
}
2.2.4 windowIcon(窗口图标)
- 核心 API:
windowIcon()(获取图标)、setWindowIcon(const QIcon& icon)(设置图标) - 代码示例(通过 qrc 管理资源,避免路径问题):
-
创建 Qt Resource File(qrc),前缀设为
/,添加图片资源(如 rose.jpg);

- 注意: 添加的⽂件必须是在 qrc 文件的同级目录 , 或者同级目录的子目录中. 因此我们需要把其他盘的 rose.jpg 复制到上述⽬录中。
- 再将prc文件添加进项目文件配置:
RESOURCES += picture.qrc
-
编写代码:
cpp
#include <QIcon>
Widget::Widget(QWidget *parent)
: QWidget(parent), ui(new Ui::Widget)
{
ui->setupUi(this);
QIcon icon(":/rose.jpg"); // 从 qrc 中读取资源(: 表示资源路径)
this->setWindowIcon(icon);
}
- 资源管理说明:qrc 是 XML 格式的资源配置文件,会将资源二进制数据编译到 exe 中,实现"路径无关",避免绝对路径导致的资源丢失问题(适合管理图片、字体等静态资源)。
2.2.5 windowOpacity(透明度)
windowOpacity(透明度调整)、setWindowOpacity(float n):获取到控件的不透明数值. 返回 float, 取值为 0.0 -> 1.0 其中 0.0 表⽰全透明, 1.0 表示完全不透明.
cpp
// 增加透明度
void Widget::on_pushButton_add_clicked()
{
float opacity = this->windowOpacity();
if (opacity < 1.0) opacity += 0.1;
this->setWindowOpacity(opacity);
}
// 降低透明度
void Widget::on_pushButton_sub_clicked()
{
float opacity = this->windowOpacity();
if (opacity > 0.0) opacity -= 0.1;
this->setWindowOpacity(opacity);
}
2.2.6 cursor(鼠标光标)
| 函数声明 | 功能说明 |
|---|---|
| QPixmap::QPixmap(const QString& fileName) | 实例化QPixmap对象,从指定文件路径加载图片资源 |
| QPixmap QPixmap::scaled(int width, int height) | 按指定宽度和高度缩放QPixmap对象,返回缩放后的新QPixmap对象(原对象不变) |
| QCursor::QCursor(const QPixmap& pixmap, int hotX, int hotY) | 创建自定义QCursor对象,绑定位图并指定光标"热点"(点击有效位置)坐标 |
| void QWidget::setCursor(const QCursor& cursor) | 为当前Widget设置自定义光标,仅鼠标悬停该Widget时生效 |
cpp
// 可以直接通过ui修改
// 代码设置光标为等待状态
#include <QPushButton>
Widget::Widget(QWidget *parent)
: QWidget(parent), ui(new Ui::Widget)
{
ui->setupUi(this);
QPixmap pixmap(":/favicon.png");
// 缩放图⽚为 64 * 64 的尺⼨.
pixmap = pixmap.scaled(64, 64);
// 创建 QCursor 对象, 并指定 "热点"(⿏标点击时生效的位置) 为 (2, 2) 坐标位置,默认生效位置在左上角。
QCursor cursor(pixmap, 2, 2);
// 设置光标
this->setCursor(cursor);
}
2.2.7 font(字体设置)
- 可以通过 ui 直接修改:

- 还可以通过 API修改:
| 分类 | 名称/属性 | 函数声明/说明 |
|---|---|---|
| API | font() | 获取当前widget的字体信息,返回QFont对象 |
| API | setFont(const QFont& font) | 设置当前widget的字体信息 |
| QFont属性 | family | 字体家族,比如"楷体""宋体""微软雅黑"等 |
| QFont属性 | pointSize | 字体大小 |
| QFont属性 | weight | 字体粗细,取值范围[0,99],数值越大越粗 |
| QFont属性 | bold | 是否加粗:true对应weight=75,false对应weight=50 |
| QFont属性 | italic | 是否倾斜 |
| QFont属性 | underline | 是否带有下划线 |
| QFont属性 | strikeOut | 是否带有删除线 |
cpp
Widget::Widget(QWidget *parent)
: QWidget(parent), ui(new Ui::Widget)
{
ui->setupUi(this);
QFont font;
font.setFamily("仿宋"); // 字体家族
font.setPointSize(20); // 字体大小
font.setBold(true); // 加粗
font.setItalic(true); // 倾斜
ui->label->setFont(font);
}
2.2.8 toolTip (提示说明)
| API | 说明 |
|---|---|
| setToolTip | 设置toolTip,鼠标悬停在该widget上时会显示提示说明 |
| setToolTipDuration | 设置toolTip的提示时间(单位:ms),时间结束后toolTip会自动消失 |
cpp
Widget::Widget(QWidget *parent)
: QWidget(parent), ui(new Ui::Widget)
{
ui->setupUi(this);
// 设置提示文本
ui->pushButton->setToolTip("<font color='#336699' size='3'>点击该按钮执行提交操作</font>");
// 设置提示显示时长(单位:毫秒,-1表示一直显示直到鼠标移开)
ui->pushButton->setToolTipDuration(3000); // 鼠标悬停后提示显示3秒自动消失
}
2.2.9 toolTip (提示说明)
focusPolicy()
- 获取当前Widget的"焦点策略",返回
Qt::FocusPolicy类型的枚举值(即当前Widget是如何接收键盘焦点的)。
setFocusPolicy(Qt::FocusPolicy policy)
- 设置当前Widget的"焦点策略"(决定Widget通过什么方式接收键盘焦点),参数
policy是Qt::FocusPolicy枚举类型,具体取值及含义如下:
| 枚举值 | 含义 |
|---|---|
Qt::NoFocus |
控件不会接收任何键盘焦点(比如纯展示用的Label,通常设这个) |
Qt::TabFocus |
控件只能通过Tab键切换的方式接收焦点(比如表单中的输入框,按Tab能切到它) |
Qt::ClickFocus |
控件只能通过鼠标点击的方式接收焦点(比如按钮,点击后获得焦点) |
Qt::StrongFocus |
控件可以通过Tab键切换 + 鼠标点击两种方式接收焦点(大部分交互控件的默认值) |
Qt::WheelFocus |
类似StrongFocus,还额外支持鼠标滚轮触发焦点(很少用) |
cpp
Widget::Widget(QWidget *parent)
: QWidget(parent), ui(new Ui::Widget)
{
ui->setupUi(this);
//设置lineedit只能通过tab获得焦点
ui->lineEdit->setFocusPolicy(Qt::TabFocus);
}
三、QSS 界面设计
Qt Style Sheet(简称 QSS)是 Qt 框架借鉴CSS(层叠样式表) 语法设计的界面美化机制,用于自定义 Qt 控件(Widget)的外观(颜色、字体、边框、布局等),无需修改控件源码,即可实现跨平台的界面风格统一,是 Qt 界面美化的核心工具。
QSS语法与CSS高度相似,核心由「选择器」和「声明块」组成:
css
选择器 {
样式属性1: 值1;
样式属性2: 值2;
/* 注释 */
}
- 选择器:指定要应用样式的控件(如QPushButton、#btnOK等);
- 声明块 :
{}内的样式规则,以「属性:值」形式书写,末尾必须加;,支持多行/单行书写。
常用样式属性
QSS支持CSS核心属性,同时新增Qt专属属性,以下是最常用的类别:
| 样式类别 | 常用属性 | 示例值 |
|---|---|---|
| 背景 | background-color | #4CAF50(十六进制)、red、rgb(76,175,80) |
| background-image | url(:/images/btn_bg.png)(资源文件) | |
| background-repeat | no-repeat(不重复)、repeat-x(横向重复) | |
| 字体/文字 | color | white、#333333 |
| font-size | 14px、16pt | |
| font-family | 微软雅黑、Arial | |
| text-align | center、left | |
| 边框 | border | 1px solid #ccc(宽度+样式+颜色) |
| border-radius | 8px(圆角半径,实现圆角控件) | |
| border-left-color | #f00(单独设置左边框颜色) | |
| 尺寸/布局 | width/height | 100px、80px |
| padding | 5px(内边距)、2px 5px(上下/左右) | |
| margin | 3px(外边距) | |
| Qt专属 | qproperty-icon | url(:/icons/ok.png)(设置控件图标) |
| qproperty-toolTipStyle | 自定义提示框样式 |
QSS中颜色的表示
像素与颜色的基础逻辑
- 计算机屏幕的显示单元是"像素"(一个发光的光点);
- 每个像素的颜色由 R(红)、G(绿)、B(蓝)三个通道 共同决定,每个通道用1个字节 表示(取值范围是十进制
0-255,或十六进制0x00-0xFF); - 通过调整R、G、B的数值比例,就能混合出所有可见颜色。
常用颜色的表示方式
RGB颜色有3种常用写法(以纯红、纯绿等为例):
| 颜色 | RGB写法(十进制) | 十六进制完整写法 | 十六进制简写 |
|---|---|---|---|
| 纯红 | rgb(255, 0, 0) |
#FF0000 |
#F00 |
| 纯绿 | rgb(0, 255, 0) |
#00FF00 |
#0F0 |
| 纯蓝 | rgb(0, 0, 255) |
#0000FF |
#00F |
| 纯白 | rgb(255,255,255) |
#FFFFFF |
#FFF |
| 纯黑 | rgb(0, 0, 0) |
#000000 |
#000 |
基础颜色设置
1. 纯色背景(最常用)
通过 background-color 设置页面背景色,支持多种颜色格式:
css
/* 方式1:十六进制颜色(推荐,支持透明通道) */
QWidget {
background-color: #f5f5f5; /* 浅灰色 */
}
/* 方式2:预定义颜色名 */
QWidget {
background-color: lightblue; /* 预定义浅蓝色 */
}
/* 方式3:RGB/RGBA(A是透明度,0-255) */
QWidget {
background-color: rgb(245, 245, 245); /* 同#f5f5f5 */
background-color: rgba(245, 245, 245, 200); /* 带透明度的浅灰色 */
}
2. 文字颜色(前景色)
通过 color 设置页面内文字的颜色(仅影响当前控件的文字,子控件需单独设置):
css
QWidget {
color: #333333; /* 文字为深灰色 */
}
高级背景效果
1. 渐变背景
QSS支持线性渐变 和径向渐变,让页面背景更丰富:
css
/* 线性渐变:从顶部到底部,从浅蓝到深蓝 */
QWidget {
background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
stop:0 #e6f7ff, stop:1 #1890ff);
}
/* 径向渐变:从中心向外,从浅绿到深绿 */
QWidget {
background: qradialgradient(cx:0.5, cy:0.5, radius:0.5,
stop:0 #dfffdf, stop:1 #52c41a);
}
qlineargradient参数:x1/y1(渐变起点)、x2/y2(渐变终点),stop:位置 颜色(位置范围0-1);qradialgradient参数:cx/cy(渐变中心)、radius(渐变半径)。
2. 背景图+颜色叠加
可同时设置背景图和背景色(背景图会覆盖在颜色上层,支持透明图):
css
QWidget {
background-color: #f0f0f0; /* 底色 */
background-image: url(:/images/bg_pattern.png); /* 叠加背景图 */
background-repeat: repeat; /* 背景图平铺(默认),可选no-repeat/repeat-x等 */
background-position: center; /* 背景图居中显示 */
}
子控件与页面的颜色层级
页面(父控件)的颜色设置会影响子控件,但子控件可单独覆盖:
css
/* 页面背景设为浅灰,文字深灰 */
QWidget {
background-color: #f5f5f5;
color: #333;
}
/* 页面内的按钮单独设背景色和文字色 */
QWidget QPushButton {
background-color: #1890ff;
color: white;
}
透明度与半透明页面
通过 rgba 或 opacity 实现页面半透明(opacity 会影响控件及其所有子控件):
css
/* 仅背景色半透明,文字不透明 */
QWidget {
background-color: rgba(245, 245, 245, 150); /* A=150(0完全透明,255不透明) */
}
/* 整个页面(包括子控件)半透明 */
QWidget {
opacity: 0.8; /* 0完全透明,1不透明 */
}
通过Designer修改QSS

通过代码修改QSS
cpp
Widget::Widget(QWidget *parent)
: QWidget(parent), ui(new Ui::Widget)
{
ui->setupUi(this);
ui->pushButton_target->setStyleSheet(
"font-family:'JetBrains Mono';font-size: 18px;background-color: #282C34; color: yellow"
);
}