
🔥小叶-duck:个人主页
❄️个人专栏:《Data-Structure-Learning》《C++入门到进阶&自我学习过程记录》
《Linux操作系统从入门到实践》《Qt从入门到实践》
《算法题讲解指南》--优选算法
《算法题讲解指南》--递归、搜索与回溯算法
《算法题讲解指南》--动态规划算法
✨未择之路,不须回头
已择之路,纵是荆棘遍野,亦作花海遨游
目录
[1.1 方式1:图形化方式创建helloworld](#1.1 方式1:图形化方式创建helloworld)
[1.2 方式2:代码创建helloworld](#1.2 方式2:代码创建helloworld)
[二、Qt 内存管理核心:对象树机制(避免内存泄漏)](#二、Qt 内存管理核心:对象树机制(避免内存泄漏))
[2.1 对象树核心原理](#2.1 对象树核心原理)
[2.2 对象树实战验证](#2.2 对象树实战验证)
[2.3 避坑指南](#2.3 避坑指南)
[3.1 方式1:图形化方式创建helloworld](#3.1 方式1:图形化方式创建helloworld)
[3.2 代码创建helloworld](#3.2 代码创建helloworld)
[4.1 方式1:图形化方式创建helloworld](#4.1 方式1:图形化方式创建helloworld)
[4.2 方式2:代码创建helloworld](#4.2 方式2:代码创建helloworld)
[五、Qt 窗口坐标体系](#五、Qt 窗口坐标体系)
[5.1 核心规则](#5.1 核心规则)
[5.2 常用位置操作函数](#5.2 常用位置操作函数)
[5.3 实战示例:居中显示组件](#5.3 实战示例:居中显示组件)
[六、Qt 开发关键技巧与避坑汇总](#六、Qt 开发关键技巧与避坑汇总)
[6.1 命名规范](#6.1 命名规范)
[6.2 常用快捷键](#6.2 常用快捷键)
[6.3 帮助文档使用](#6.3 帮助文档使用)
前言
Qt 作为主流跨平台 GUI 开发框架,入门阶段打好基础尤为关键。本文结合从零创建 HelloWorld、手写代码实现界面、内存泄露与对象树机制、中文乱码问题排查,以及按钮 / 输入框基础控件、命名规范、文档查询、Qt 坐标系等核心知识点,梳理 Qt 初识阶段的完整学习脉络,帮新手快速夯实 Qt 开发底层认知,为后续界面开发与项目实战做好铺垫。
一、标签(QLabel)实现helloworld
1.1 方式1:图形化方式创建helloworld
- 拖拽 "Label" 组件到 UI 设计窗口,双击修改文本为 "Qt 进阶实战";
- 在属性设置区设置:
font:点击右侧 "...",选择字体、大小并勾选加粗;styleSheet:输入color: red;设置文本颜色;alignment:选择 "水平居中 + 垂直居中";
- 拖动标签到目标位置,或通过
geometry属性精确设置坐标。


1.2 方式2:代码创建helloworld

代码简单实现hello world:
cpp
#include "widget.h"
#include "ui_widget.h"
#include <QLabel>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
QLabel *label = new QLabel(this);
//更推荐在堆上创建的方式:
//label->setText(QString("hello world"));
label->setText("hello world");//可以不显式写构造函数,直接传字符串会进行隐式类型转换
}
...




虽然可以在栈上创建label,但是只是可以创建,而无法实现功能,原因就是当函数结束的时候会进行出栈,而在栈上创建的局部变量就会连同一起被销毁,就会导致运行程序的时候界面上没有标签的结果展示。

最后,可以演示一下带字体、颜色、位置设置等的完整实现:
cpp
#include "widget.h"
#include "ui_widget.h"
#include <QLabel>
#include <QFont> // 字体头文件
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
// 1. 设置窗口固定大小
this->setFixedSize(800, 600);
// 2. 创建标签,指定父对象
QLabel *label = new QLabel(this);
// 3. 设置标签文本
label->setText("Hello QT");
// 4. 设置字体(字体类型+大小+加粗)
QFont font("微软雅黑", 24, QFont::Bold);
label->setFont(font);
// 5. 设置文本颜色(红色)
label->setStyleSheet("color: red;");
// 6. 设置标签位置(居中显示)
label->move((800 - label->width())/2, 200);
}
...

二、Qt 内存管理核心:对象树机制(避免内存泄漏)
Qt 最具特色的就是 "对象树" 内存管理机制,无需手动释放大多数组件,大幅简化内存管理。

2.1 对象树核心原理
- 父对象与子对象 :当创建 QObject 子类对象时,指定父对象(如
new QPushButton(this)),子对象会自动加入父对象的children()列表; - 自动析构:父对象析构时,会遍历children()列表,自动删除所有子对象,避免内存泄漏;
- 适用范围:所有继承自 QObject 的类(如 QWidget、QPushButton、QLabel 等核心组件)。

2.2 对象树实战验证
通过自定义MyLabel类,观察构造和析构顺序
1、选中工程名,鼠标右键----->"add new..."(或"添加新文件")


2、选择"choose...",弹出如下界面;

3、点击"完成"之后,手动创建类的头文件以及源文件会自动添加到目标工程中;



乱码问题:




代码展示:
cpp
//mylabel.h
#ifndef MYLABEL_H
#define MYLABEL_H
#include <QLabel>
class MyLabel : public QLabel
{
public:
//构造函数使用带 QWidget* 参数
//这样才能确保我们的对象能够加到对象树上
MyLabel(QWidget* parent);
~MyLabel();
};
#endif // MYLABEL_H
//mylabel.cpp
#include "mylabel.h"
#include <iostream>
#include <QDebug>
MyLabel::MyLabel(QWidget* parent)
:QLabel(parent) //派生类的构造函数,需先调用父类构造函数构造父类成员变量再构造子类成员变量
{}
MyLabel::~MyLabel()
{
//std::cout << "MyLabel 被销毁" << std::endl;
qDebug() << "MyLabel 被销毁";
}
//widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include "mylabel.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
MyLabel *label = new MyLabel(this);
label->setText("Hello world!");
}
Widget::~Widget()
{
delete ui;
}

结论:子对象(标签)的析构在父对象(窗口)析构之后,对象树确保所有子组件被自动释放。
2.3 避坑指南
- 不要手动删除子对象 :若手动
delete btn,父对象析构时会再次删除,导致双重释放崩溃; - 优先在构造时指定父对象 :避免后续通过
setParent()设置(可能导致析构顺序混乱); - 栈上对象也支持对象树:如
QPushButton btn(this),析构时同样会被父对象管理。

三、编辑框(QLineEdit)实现helloworld
3.1 方式1:图形化方式创建helloworld

3.2 代码创建helloworld
由于编辑框使用纯代码创建helloworld,和标签基本一致,这里就直接展示代码不过多讲解了:
cpp
//widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QLineEdit>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
QLineEdit* edit = new QLineEdit(this);
edit->setText("Hello World");
}
Widget::~Widget()
{
delete ui;
}
四、按钮(QPushButton)实现helloworld
4.1 方式1:图形化方式创建helloworld
通过 Qt Creator 的 UI 设计器拖拽组件,无需手动编写布局代码:
-
双击项目中的
widget.ui文件,进入设计模式; -
在左侧 "组件选择区" 找到 "Push Button",拖拽到中间的 UI 设计窗口;
-
选中按钮,在右侧 "属性设置区" 修改属性:
text:设置按钮文本(如 "点击测试");geometry:设置位置和大小(x=100, y=100, 宽 = 120, 高 = 40);objectName:设置组件唯一标识(如 "myButton",后续代码中可通过ui->myButton访问);
- 直接构建运行,界面自动生效。
依靠一些信号槽代码实现一下按钮的切换:(后面会详细讲解这个知识点的)
cpp
//widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
void handleClick();
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
//widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//从ui界面获取到pushButton按钮
connect(ui->pushButton, &QPushButton::clicked, this, &Widget::handleClick);
}
Widget::~Widget()
{
delete ui;
}
void Widget::handleClick()
{
//当按钮被点击之后,就把按钮中的文本,进行切换
if(ui->pushButton->text() == QString("Hello world"))
{
ui->pushButton->setText("Hello Qt");
}
else
{
ui->pushButton->setText("Hello world");
}
}



4.2 方式2:代码创建helloworld
无需依赖.ui 文件,直接通过代码创建按钮并设置属性,适合动态生成组件的场景:
cpp
//widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QPushButton>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
void handleClick();
private:
Ui::Widget *ui;
QPushButton* myButton; //关键一步
//因为按下按钮执行的函数操作也需要myButton,如果只是在构造函数里面定义则无法在其他函数中使用
//而这些函数都是Widget的成员函数,所以可以把这个变量作为成员变量使用
};
#endif // WIDGET_H
//widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
myButton = new QPushButton(this);
myButton->setText("Hello world");
connect(myButton, &QPushButton::clicked, this, &Widget::handleClick);
}
Widget::~Widget()
{
delete ui;
}
void Widget::handleClick()
{
if(myButton->text() == QString("Hello world"))
{
myButton->setText("Hello Qt");
}
else
{
myButton->setText("Hello world");
}
}


五、Qt 窗口坐标体系
Qt 坐标体系是组件布局的基础,核心规则如下:
5.1 核心规则
- 原点(0,0):窗口左上角;
- 坐标轴方向:x 轴向右递增,y 轴向下递增;
- 嵌套组件:子组件的坐标相对于父组件的左上角,而非屏幕。




5.2 常用位置操作函数
cpp
// 1. 设置组件位置(x, y)
btn->move(100, 200);
// 2. 设置组件大小(宽, 高)
btn->resize(120, 40);
// 3. 设置固定大小(不可拉伸)
btn->setFixedSize(120, 40);
// 4. 获取组件位置和大小
int x = btn->x(); // 获取x坐标
int y = btn->y(); // 获取y坐标
QSize size = btn->size(); // 获取大小
QRect rect = btn->geometry(); // 获取位置+大小(x, y, 宽, 高)

5.3 实战示例:居中显示组件
cpp
//widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
// 让按钮在800x600的窗口中居中
QPushButton *lab = new QPushButton("居中显示", this);
lab->setFixedSize(200, 50);
// 计算居中坐标:(窗口宽-组件宽)/2, (窗口高-组件高)/2
int x = (this->width() - lab->width()) / 2;
int y = (this->height() - lab->height()) / 2;
lab->move(x, y);
}
Widget::~Widget()
{
delete ui;
}

六、Qt 开发关键技巧与避坑汇总
6.1 命名规范
- 类名 :首字母大写,单词间首字母大写(如
MyPushButton); - 函数名 / 变量名 :首字母小写,单词间首字母大写(如
setFixedSize、testBtn); - 文件名 :与类名一致(如
MyPushButton.h、MyPushButton.cpp)。

6.2 常用快捷键
Ctrl+/:快速注释 / 取消注释;Ctrl+R:运行项目;Ctrl+B:构建项目(编译);F4:在.h 和.cpp 文件间快速切换;F1:打开选中类 / 函数的官方文档(优先看英文文档,准确性更高);Ctrl+I:代码自动对齐。
6.3 帮助文档使用
Qt 帮助文档是最佳学习资料,三种打开方式:
- 光标选中类名(如
QPushButton),按F1; - 打开 Qt Creator,点击左侧 "帮助" 模式;
- 找到 Qt 安装目录下的
bin\assistant.exe,双击打开独立帮助窗口。
结束语
本篇博客围绕 Qt 入门核心内容展开,从 QLabel、QLineEdit、QPushButton 等基础控件的图形化与代码实现,到 Qt 对象树内存管理机制、窗口坐标体系,系统梳理了新手入门必备的知识点与实用技巧。同时总结了开发中的命名规范、快捷键、帮助文档使用等实用经验,帮助大家避开常见开发误区。希望对大家学习Qt能有所收获!