Qt 初识核心:从 HelloWorld 到基础控件,吃透对象树与内存管理

🔥小叶-duck个人主页

❄️个人专栏《Data-Structure-Learning》《C++入门到进阶&自我学习过程记录》
《Linux操作系统从入门到实践》《Qt从入门到实践》
《算法题讲解指南》--优选算法
《算法题讲解指南》--递归、搜索与回溯算法
《算法题讲解指南》--动态规划算法

未择之路,不须回头
已择之路,纵是荆棘遍野,亦作花海遨游


目录

前言

一、标签(QLabel)实现helloworld

[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 避坑指南)

三、编辑框(QLineEdit)实现helloworld

[3.1 方式1:图形化方式创建helloworld](#3.1 方式1:图形化方式创建helloworld)

[3.2 代码创建helloworld](#3.2 代码创建helloworld)

四、按钮(QPushButton)实现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能有所收获!

相关推荐
我的xiaodoujiao3 小时前
API 接口自动化测试详细图文教程学习系列19--添加封装其他的方法
开发语言·python·学习·测试工具·pytest
Co_Hui3 小时前
Java: 集合
java·开发语言
ch.ju3 小时前
Java程序设计(第3版)第四章——动态部分
java·开发语言
诙_3 小时前
C++学习总结
开发语言·c++·学习
2401_865439633 小时前
探索JavaScript对象创建的灵活方式
开发语言·javascript·ecmascript
程序猿~厾罗3 小时前
回归更新,一个简单的重新认识
开发语言
我命由我123453 小时前
Android 开发:Unable to start service Intent { ... } U=0: not found
android·开发语言·android studio·android jetpack·android-studio·android runtime
三品吉他手会点灯3 小时前
C语言学习笔记 - 34.数据类型 - 编程规范与高效学习方法
c语言·开发语言·笔记·学习
一条鱼头3 小时前
c++11语法点
开发语言·c++