在 Qt 的 GUI 开发世界里,
QWidget绝对是当之无愧的 “老大哥”。它是所有可视化控件的基类,就像盖房子的地基,不管是按钮、输入框还是复杂的表格,统统都继承自它。想要玩转 Qt 界面开发,不把QWidget的核心属性和用法啃透,那可真是寸步难行。今天这篇文章,就带大家从零开始,深挖QWidget的控件概述和核心属性(enabled、geometry、windowTitle、windowIcon、windowOpacity),用最通俗的语言和实战代码,把这些知识点揉碎了讲清楚!下面就让我们正式开始吧!
在 Qt 中,Widget(控件)是构成图形化界面的基本要素,英文原义是 “小部件”,咱们可以把它理解成搭建界面的 “积木块”。想象一下,你打开一个软件,看到的按钮、输入框、下拉菜单、滚动条,甚至是树形列表,这些都是 Qt 中的控件。

比如一个简单的 Qt 窗口程序,里面可能包含这些常见控件:
这些控件各司其职,组合在一起就形成了我们日常使用的软件界面。下面是一个最基础的 Qt 窗口程序示例,仅需几行代码就能创建一个包含QWidget的窗口:
#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()进入应用程序的事件循环。
Qt 作为成熟的 GUI 开发框架,内置了海量常用控件,在 Qt Designer 中我们能直观看到这些控件的分类:
除了现成的控件,Qt 还支持自定义控件。当内置控件满足不了需求时,我们可以基于现有控件扩展,甚至从零打造全新的控件,这让 Qt 的界面开发灵活性拉满。
控件并非 Qt 独有,而是 GUI 开发的通用概念,它的发展大致分为三个阶段:



对比前端的 Element-UI,Qt 自带控件的颜值可能稍逊一筹,但胜在跨平台性和功能的稳定性,是桌面端 GUI 开发的首选之一。
QWidget是所有 Qt 控件的父类,它包含了整个控件体系中最通用的属性。这些属性既可以在 Qt Designer 中可视化修改,也能通过代码动态调整,是我们控制控件外观和行为的核心。接下来,我们逐个拆解最常用的核心属性。
QWidget的属性多达数十个,涵盖了控件的可用性、位置尺寸、外观样式、交互行为等方方面面。下表列出了后续要重点讲解的属性及其作用:
属性名 | 作用 |
|---|---|
enabled | 设置控件是否可使用,true 为可用,false 为禁用 |
geometry | 控件的位置和尺寸,包含 x、y、width、height 四个参数 |
windowTitle | 设置顶层 Widget 的窗口标题 |
windowIcon | 设置顶层 Widget 的窗口图标 |
windowOpacity | 设置窗口的透明度,取值 0.0(全透明)~1.0(完全不透明) |
这些属性是 Qt 界面开发的 “高频考点”,掌握它们就能轻松实现控件的基础控制。
enabled属性决定了控件是否能响应用户的交互操作。当控件被禁用(enabled = false)时,不仅无法接收点击、输入等事件,外观上还会变成灰色,给用户直观的视觉反馈。
API | 说明 |
|---|---|
isEnabled() | 获取控件的可用状态,返回 bool 值 |
setEnabled(bool) | 设置控件的可用状态,true 启用,false 禁用 |
我们先创建一个默认禁用的按钮,看看效果:

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

实际开发中,我们经常需要根据业务逻辑动态切换控件的状态。比如通过一个按钮来控制另一个按钮的启用 / 禁用:
objectName分别为pushButton(目标按钮)和pushButton_enable(切换按钮);
//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);
}
}运行程序后,点击 “切换可用状态”,目标按钮会在启用(可点击)和禁用(灰色不可点)之间切换,控制台会输出状态变化的日志。


geometry属性是控件位置和尺寸的 “集合体”,它包含四个核心参数:
Qt 采用左手坐标系,原点在父控件的左上角,x 轴向右递增,y 轴向下递增,这一点一定要记牢!
API | 说明 |
|---|---|
geometry() | 获取控件的位置和尺寸,返回 QRect 对象(包含 x、y、width、height) |
setGeometry(QRect) | 通过 QRect 对象设置控件位置和尺寸 |
setGeometry(int x, int y, int width, int height) | 直接通过四个参数设置位置和尺寸 |
我们实现一个简单的功能:通过四个方向按钮控制目标按钮的上下左右移动。
objectName分别为: pushButton_target:目标按钮;pushButton_up:向上按钮;pushButton_down:向下按钮;pushButton_left:向左按钮;pushButton_right:向右按钮。
// 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 个像素为步长移动。


在 Qt 中,当Widget作为顶层窗口(带有标题栏、最小化 / 最大化 / 关闭按钮)时,geometry和frameGeometry会有差异:
我们通过代码验证一下:
// 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大(包含了窗口边框)。

windowTitle属性用于设置顶层Widget的窗口标题,也就是窗口左上角显示的文字。这个属性仅对顶层窗口有效,子控件设置该属性不会有任何效果。
API | 说明 |
|---|---|
windowTitle() | 获取窗口标题,返回 QString |
setWindowTitle(const QString& title) | 设置窗口标题 |

运行程序后,窗口的标题栏会显示 “这是窗口标题”。我们添加了一个按钮,点击后就会修改标题为“通过按钮设置窗口标题”。
windowIcon属性用于设置顶层Widget的窗口图标,这个图标会显示在窗口左上角、任务栏中,是窗口的 “视觉标识”。和windowTitle一样,该属性仅对顶层窗口有效。
API | 说明 |
|---|---|
windowIcon() | 获取窗口图标,返回 QIcon 对象 |
setWindowIcon(const QIcon& icon) | 设置窗口图标 |
// 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"),推荐使用/避免转义错误。
直接使用绝对路径存在隐患:如果用户电脑上没有该路径的图片,图标就会加载失败。Qt 提供了qrc 资源文件机制,将图片打包到程序中,实现 “路径无关” 的资源管理。
创建 qrc 资源文件:
resource.qrc;resource.qrc,点击 “Add Prefix” 添加前缀(如/),再点击 “Add Files” 添加图片文件(将 anno.jpg 复制到项目目录下)。
通过 qrc 设置图标:
// 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++ 代码,打包到可执行文件中,这样无论程序放到哪个目录,都能正常加载图标。如下所示:

windowOpacity属性用于设置窗口的透明度,取值范围是 0.0(完全透明)到 1.0(完全不透明)。通过这个属性,我们可以实现窗口的淡入淡出、半透明等炫酷效果。
API | 说明 |
|---|---|
windowOpacity() | 获取窗口透明度,返回 float 值 |
setWindowOpacity(float n) | 设置窗口透明度,n∈[0.0,1.0] |
我们实现一个功能:通过两个按钮分别增加和减少窗口的透明度。
在 Qt Designer 中拖入两个按钮,objectName为pushButton_add(增加透明度)和pushButton_sub(减少透明度);
编写按钮的点击事件槽函数:
// 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 可能略有差异,但核心用法一致。如果大家在学习过程中有任何问题,欢迎在评论区留言交流~