目录
[一、Qt 控件概述:图形界面的 "积木块"](#一、Qt 控件概述:图形界面的 “积木块”)
[1.1 什么是控件?](#1.1 什么是控件?)
[1.2 Qt 控件的 "家族体系"](#1.2 Qt 控件的 “家族体系”)
[1.3 控件体系的发展历程](#1.3 控件体系的发展历程)
[二、QWidget 核心属性:掌控控件的 "生杀大权"](#二、QWidget 核心属性:掌控控件的 “生杀大权”)
[2.1 核心属性概览](#2.1 核心属性概览)
[2.2 enabled:控件的 "启用 / 禁用" 开关](#2.2 enabled:控件的 “启用 / 禁用” 开关)
[2.2.1 核心 API](#2.2.1 核心 API)
[2.2.2 代码示例 1:创建禁用状态的按钮](#2.2.2 代码示例 1:创建禁用状态的按钮)
[2.2.3 代码示例 2:动态切换控件的启用状态](#2.2.3 代码示例 2:动态切换控件的启用状态)
[2.3 geometry:控件的 "位置与尺寸" 管家](#2.3 geometry:控件的 “位置与尺寸” 管家)
[2.3.1 核心 API](#2.3.1 核心 API)
[2.3.2 代码示例 1:控制按钮的位置移动](#2.3.2 代码示例 1:控制按钮的位置移动)
[2.3.3 geometry 与 frameGeometry 的区别](#2.3.3 geometry 与 frameGeometry 的区别)
[2.4 windowTitle:给窗口加个 "名字牌"](#2.4 windowTitle:给窗口加个 “名字牌”)
[2.4.1 核心 API](#2.4.1 核心 API)
[2.4.2 代码示例:设置窗口标题](#2.4.2 代码示例:设置窗口标题)
[2.5 windowIcon:给窗口换个 "头像"](#2.5 windowIcon:给窗口换个 “头像”)
[2.5.1 核心 API](#2.5.1 核心 API)
[2.5.2 代码示例 1:通过绝对路径设置图标](#2.5.2 代码示例 1:通过绝对路径设置图标)
[2.5.3 代码示例 2:通过 Qt 资源文件(qrc)设置图标](#2.5.3 代码示例 2:通过 Qt 资源文件(qrc)设置图标)
[2.6 windowOpacity:给窗口加个 "透明滤镜"](#2.6 windowOpacity:给窗口加个 “透明滤镜”)
[2.6.1 核心 API](#2.6.1 核心 API)
[2.6.2 代码示例:动态调整窗口透明度](#2.6.2 代码示例:动态调整窗口透明度)
前言
在 Qt 的 GUI 开发世界里,
QWidget绝对是当之无愧的 "老大哥"。它是所有可视化控件的基类,就像盖房子的地基,不管是按钮、输入框还是复杂的表格,统统都继承自它。想要玩转 Qt 界面开发,不把QWidget的核心属性和用法啃透,那可真是寸步难行。今天这篇文章,就带大家从零开始,深挖QWidget的控件概述和核心属性(enabled、geometry、windowTitle、windowIcon、windowOpacity),用最通俗的语言和实战代码,把这些知识点揉碎了讲清楚!下面就让我们正式开始吧!
一、Qt 控件概述:图形界面的 "积木块"
1.1 什么是控件?
在 Qt 中,**Widget(控件)**是构成图形化界面的基本要素,英文原义是 "小部件",咱们可以把它理解成搭建界面的 "积木块"。想象一下,你打开一个软件,看到的按钮、输入框、下拉菜单、滚动条,甚至是树形列表,这些都是 Qt 中的控件。

比如一个简单的 Qt 窗口程序,里面可能包含这些常见控件:
- 按钮(PushButton):点击触发操作;
- 单行输入框(Line Edit):输入文字;
- 多行输入框(Text Edit):输入大段文本;
- 下拉框(Combo Box):选择预设选项;
- 滚动条(Scroll Bar):浏览超出界面的内容;
- 树形视图(Tree View) 、列表视图(List View):展示结构化数据。
这些控件各司其职,组合在一起就形成了我们日常使用的软件界面。下面是一个最基础的 Qt 窗口程序示例,仅需几行代码就能创建一个包含QWidget的窗口:
cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
这段代码创建了一个 Qt 应用程序对象QApplication,实例化了自定义的Widget(继承自QWidget),并通过**show()方法显示窗口,最后通过exec()**进入应用程序的事件循环。
1.2 Qt 控件的 "家族体系"
Qt 作为成熟的 GUI 开发框架,内置了海量常用控件,在Qt Designer 中我们能直观看到这些控件的分类:
- 按钮类:Push Button、Radio Button、Check Box 等;
- 输入类:Line Edit、Text Edit、Spin Box 等;
- 视图类:List View、Tree View、Table View 等;
- 容器类:Group Box、Tab Widget、Scroll Area 等。
除了现成的控件,Qt 还支持自定义控件。当内置控件满足不了需求时,我们可以基于现有控件扩展,甚至从零打造全新的控件,这让 Qt 的界面开发灵活性拉满。
1.3 控件体系的发展历程
控件并非 Qt 独有,而是 GUI 开发的通用概念,它的发展大致分为三个阶段:
- 无控件时代 :需要通过绘图 API 手动绘制按钮、输入框,代码编写极其繁琐,比如早期文曲星的 Lava 平台开发;
- 粗略控件时代 :仅提供按钮、输入框、单选框等最基础的控件,功能简单,比如 HTML 的原生控件;
- 完整控件体系时代 :覆盖 GUI 开发的大部分场景,Qt、MFC、Android SDK、前端 UI 库(如 Element-UI)都属于这一阶段,控件丰富度和美观度都有了质的飞跃。
对比前端的 Element-UI,Qt 自带控件的颜值可能稍逊一筹,但胜在跨平台性和功能的稳定性,是桌面端 GUI 开发的首选之一。
二、QWidget 核心属性:掌控控件的 "生杀大权"
QWidget是所有 Qt 控件的父类,它包含了整个控件体系中最通用的属性。这些属性既可以在 Qt Designer 中可视化修改,也能通过代码动态调整,是我们控制控件外观和行为的核心。接下来,我们逐个拆解最常用的核心属性。
2.1 核心属性概览
QWidget的属性多达数十个,涵盖了控件的可用性、位置尺寸、外观样式、交互行为等方方面面。下表列出了后续要重点讲解的属性及其作用:
| 属性名 | 作用 |
|---|---|
| enabled | 设置控件是否可使用,true 为可用,false 为禁用 |
| geometry | 控件的位置和尺寸,包含 x、y、width、height 四个参数 |
| windowTitle | 设置顶层 Widget 的窗口标题 |
| windowIcon | 设置顶层 Widget 的窗口图标 |
| windowOpacity | 设置窗口的透明度,取值 0.0(全透明)~1.0(完全不透明) |
这些属性是 Qt 界面开发的 "高频考点",掌握它们就能轻松实现控件的基础控制。
2.2 enabled:控件的 "启用 / 禁用" 开关
enabled属性决定了控件是否能响应用户的交互操作。当控件被禁用(enabled = false)时,不仅无法接收点击、输入等事件,外观上还会变成灰色,给用户直观的视觉反馈。
2.2.1 核心 API
| API | 说明 |
|---|---|
| isEnabled() | 获取控件的可用状态,返回 bool 值 |
| setEnabled(bool) | 设置控件的可用状态,true 启用,false 禁用 |
2.2.2 代码示例 1:创建禁用状态的按钮
我们先创建一个默认禁用的按钮,看看效果:

运行程序后,按钮会显示为灰色,无法被点击,这就是enabled属性的基础用法。

2.2.3 代码示例 2:动态切换控件的启用状态
实际开发中,我们经常需要根据业务逻辑动态切换控件的状态。比如通过一个按钮来控制另一个按钮的启用 / 禁用:
- 在 Qt Designer 中拖入两个按钮,
objectName分别为pushButton(目标按钮)和pushButton_enable(切换按钮);- 编写切换按钮的点击事件槽函数:
cpp
//widget.cpp
#include "ui_widget.h"
#include <QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_clicked()
{
qDebug() << "执行了槽函数";
}
void Widget::on_pushButton_enable_clicked()
{
//切换第一个按钮的禁用状态
//1.先获取到第一个按钮当前的可用状态
bool enable = ui->pushButton->isEnabled();
if(enable)
{
ui->pushButton->setEnabled(false);
}
else
{
ui->pushButton->setEnabled(true);
}
}
运行程序后,点击 "切换可用状态",目标按钮会在启用(可点击)和禁用(灰色不可点)之间切换,控制台会输出状态变化的日志。


2.3 geometry:控件的 "位置与尺寸" 管家
geometry属性是控件位置和尺寸的 "集合体",它包含四个核心参数:
- x:控件左上角的横坐标(以父控件左上角为原点);
- y:控件左上角的纵坐标;
- width:控件的宽度;
- height:控件的高度。
Qt 采用左手坐标系,原点在父控件的左上角,x 轴向右递增,y 轴向下递增,这一点一定要记牢!
2.3.1 核心 API
| API | 说明 |
|---|---|
| geometry() | 获取控件的位置和尺寸,返回 QRect 对象(包含 x、y、width、height) |
| setGeometry(QRect) | 通过 QRect 对象设置控件位置和尺寸 |
| setGeometry(int x, int y, int width, int height) | 直接通过四个参数设置位置和尺寸 |
2.3.2 代码示例 1:控制按钮的位置移动
我们实现一个简单的功能:通过四个方向按钮控制目标按钮的上下左右移动。
- 在 Qt Designer 中拖入五个按钮,**
objectName**分别为:
- pushButton_target:目标按钮;
- pushButton_up:向上按钮;
- pushButton_down:向下按钮;
- pushButton_left:向左按钮;
- pushButton_right:向右按钮。
- 编写方向按钮的点击事件槽函数:
cpp
// widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_up_clicked()
{
//获取到target本身的geometry
QRect rect = ui->pushButton_target->geometry();
qDebug() << rect;
// rect.setY(rect.y() - 5);
// ui->pushButton_target->setGeometry(rect);
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();
qDebug() << rect;
// rect.setY(rect.y() + 5);
// ui->pushButton_target->setGeometry(rect);
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();
qDebug() << rect;
// rect.setX(rect.x() - 5);
// ui->pushButton_target->setGeometry(rect);
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();
qDebug() << rect;
// rect.setX(rect.x() + 5);
// ui->pushButton_target->setGeometry(rect);
ui->pushButton_target->setGeometry(rect.x() + 5, rect.y(), rect.width(), rect.height());
}
运行程序后,点击方向按钮,目标按钮就会以 5 个像素为步长移动。


2.3.3 geometry 与 frameGeometry 的区别
在 Qt 中,当Widget作为顶层窗口(带有标题栏、最小化 / 最大化 / 关闭按钮)时,geometry和frameGeometry会有差异:
- geometry :不包含窗口边框(title bar),仅计算客户区的位置和尺寸;
- frameGeometry :包含窗口边框,计算整个窗口的位置和尺寸。
我们通过代码验证一下:
cpp
// widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QPushButton>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
QPushButton* button = new QPushButton(this);
button->setText("按钮");
button->move(100, 100);
connect(button, &QPushButton::clicked, this, &Widget::handle);
}
Widget::~Widget()
{
delete ui;
}
void Widget::handle()
{
QRect rect1 = this->geometry();
QRect rect2 = this->frameGeometry();
qDebug() << rect1;
qDebug() << rect2;
}
运行程序后,构造函数中两者的输出一致,而点击按钮后,frameGeometry的宽度和高度会比geometry大(包含了窗口边框)。

2.4 windowTitle:给窗口加个 "名字牌"
windowTitle属性用于设置顶层Widget的窗口标题,也就是窗口左上角显示的文字。这个属性仅对顶层窗口有效,子控件设置该属性不会有任何效果。
2.4.1 核心 API
| API | 说明 |
|---|---|
| windowTitle() | 获取窗口标题,返回 QString |
| setWindowTitle(const QString& title) | 设置窗口标题 |
2.4.2 代码示例:设置窗口标题
运行程序后,窗口的标题栏会显示 "这是窗口标题"。我们添加了一个按钮,点击后就会修改标题为"通过按钮设置窗口标题"。
2.5 windowIcon:给窗口换个 "头像"
windowIcon属性用于设置顶层Widget的窗口图标,这个图标会显示在窗口左上角、任务栏中,是窗口的 "视觉标识"。和windowTitle一样,该属性仅对顶层窗口有效。
2.5.1 核心 API
| API | 说明 |
|---|---|
| windowIcon() | 获取窗口图标,返回 QIcon 对象 |
| setWindowIcon(const QIcon& icon) | 设置窗口图标 |
2.5.2 代码示例 1:通过绝对路径设置图标
cpp
// widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QIcon>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
// 创建图标对象,加载本地图片(D盘的anno.jpg)
QIcon icon("d:/anno.jpg");
// 设置窗口图标
this->setWindowIcon(icon);
}
Widget::~Widget()
{
delete ui;
}
注意:Windows 系统中,路径分隔符可以用**/或转义后的\**(如
"d:\\anno.jpg"),推荐使用/避免转义错误。
2.5.3 代码示例 2:通过 Qt 资源文件(qrc)设置图标
直接使用绝对路径存在隐患:如果用户电脑上没有该路径的图片,图标就会加载失败。Qt 提供了qrc 资源文件机制,将图片打包到程序中,实现 "路径无关" 的资源管理。
创建 qrc 资源文件:
- 在 Qt Creator 中右键项目 → 新建文件 → Qt → Qt Resource File,命名为resource.qrc;
- 打开resource.qrc,点击 "Add Prefix" 添加前缀(如
/),再点击 "Add Files" 添加图片文件(将 anno.jpg 复制到项目目录下)。通过 qrc 设置图标:
cpp// widget.cpp #include "widget.h" #include "ui_widget.h" #include <QIcon> Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui->setupUi(this); // 从qrc资源中加载图标(:/表示资源路径,rose.jpg是资源文件名) QIcon icon(":/anno.jpg"); this->setWindowIcon(icon); } Widget::~Widget() { delete ui; }
Qt 会把 qrc 中的资源编译成 C++ 代码,打包到可执行文件中,这样无论程序放到哪个目录,都能正常加载图标。如下所示:

2.6 windowOpacity:给窗口加个 "透明滤镜"
windowOpacity属性用于设置窗口的透明度,取值范围是 0.0(完全透明)到 1.0(完全不透明)。通过这个属性,我们可以实现窗口的淡入淡出、半透明等炫酷效果。
2.6.1 核心 API
| API | 说明 |
|---|---|
| windowOpacity() | 获取窗口透明度,返回 float 值 |
| setWindowOpacity(float n) | 设置窗口透明度,n∈[0.0,1.0] |
2.6.2 代码示例:动态调整窗口透明度
我们实现一个功能:通过两个按钮分别增加和减少窗口的透明度。
在 Qt Designer 中拖入两个按钮,
objectName为pushButton_add(增加透明度)和pushButton_sub(减少透明度);编写按钮的点击事件槽函数:
cpp// widget.cpp #include "widget.h" #include "ui_widget.h" #include <QDebug> Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui->setupUi(this); } Widget::~Widget() { delete ui; } void Widget::on_pushButton_add_clicked() { float opacity = this->windowOpacity(); if(opacity >= 1.0) { return; } qDebug() << opacity; opacity += 0.1; this->setWindowOpacity(opacity); } void Widget::on_pushButton_sub_clicked() { float opacity = this->windowOpacity(); if(opacity <= 0.0) { return; } qDebug() << opacity; opacity -= 0.1; this->setWindowOpacity(opacity); }
运行程序后,点击 "减少透明度" 按钮,窗口会逐渐变透明;点击 "增加透明度" 按钮,窗口会逐渐恢复不透明。需要注意的是,C++ 中的 float 类型存在精度误差,比如 1.0 - 0.1 的结果并非严格等于 0.9,这是正常现象。


总结
本文我们从 Qt 控件的基本概念入手,详细讲解了
QWidget的核心属性:enabled控制控件的可用性、geometry管理控件的位置和尺寸、windowTitle设置窗口标题、windowIcon定制窗口图标、windowOpacity调整窗口透明度。这些属性是 Qt 界面开发的基础,掌握它们就能实现控件的基础控制和窗口的个性化定制。在下一篇文章中,我们会继续讲解
QWidget的其他核心属性(如 cursor、font、toolTip 等),以及按钮类、显示类等常用控件的用法。关注我,一起解锁 Qt 界面开发的更多技能!注:本文的代码示例均基于 Qt 5.14.2 版本编写,不同 Qt 版本的 API 可能略有差异,但核心用法一致。如果大家在学习过程中有任何问题,欢迎在评论区留言交流~





