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能有所收获!

相关推荐
用户805533698038 小时前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner8 小时前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz5 天前
QML Hello World 入门示例
qt
xcyxiner8 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner9 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner9 天前
DicomViewer (添加模型类)3
qt
xcyxiner10 天前
DicomViewer (目录调整) 2
qt
xcyxiner10 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
LDR00612 天前
Type-C 快充全面升级!LDR6601 赋能个人护理便携电机,重塑剃须刀 / 理发器新体验
c语言·开发语言
雪碧聊技术12 天前
Tree.js是什么?一文讲透
开发语言·javascript·ecmascript