目录
Qt hello world 程序
想要实现hello world有两种方式,一种是纯代码方式实现,通过编写代码在显示界面上创建控件来显示hello world,另一种方式是通过直接创建控件
使用"标签"实现

在QT designer的右上角我们看到,通过树形结构,显示了当前页面有哪些空间。
快捷键Ctrl+R,运行程序。

这里可以修改文本内容。
纯代码方式实现
在widget.cpp文件中Widget类对象的构造函数中创建QLabel对象,也可以实现hello world。
c
#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("hello world");
}
直接运行,就可以看到结果。

注意
- 使用QLabel的时候需要包含头文件
<QLabel>,这里QLabel可以写成<QLabel.h>,两者的写法不同可以参照C++中的头文件包含情况。- 这里不能直接在栈上创建,构造函数只会被运行一次,构造函数运行结束,栈被销毁,对象也会被销毁,运行起来时就看不到创建出的标签对象了。
- 在创建QLabel对象时,需要传入this指针,给当前对象指定一个"父对象 ",这也是后面需要讲解的对象树。
c
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
QLabel label(this);//栈上创建,构造函数完成后,QLabel对象会被销毁
label.setText("hello world");
}
//所以说这种方式是不推荐的
看到这里可能会想,在堆上申请资源,需要我们自己手动释放,如果内有释放资源,岂不是造成资源泄露了吗?
内存泄漏
这里不会内存泄漏的,有了对象树,对象树会帮我们管理资源的。
Qt的对象树是一种自动内存管理机制,通过父子关系将QObject及其子类对象组织成树状结构。当父对象被销毁时,会自动销毁其所有子对象。
对象树的主要功能
- 解决内存管理问题:C++没有自动垃圾回收,手动管理内存容易出错(内存泄漏或重复删除),对象树提供了一种自动化的内存管理方式
- 简化代码
- 便于对象查找和遍历
有了对象树的管理,就能在合适的时机(窗口关闭/销毁),对资源进行统一的释放,这也是对象树的主要目的。如果在栈上创建对象,就会导致有一些控件提前释放,在界面上就看不见了。
验证自动化内存管理
我们可以自己对QLabel类进行封装,通过终端来打印对象的析构情况。
首先,先创建文件来对QLabel对象做封装。




完成之后,就会出现myqlabel.h和myqlabel.cpp两个文件。我们需要自己来写MyQLabel类的构造函数和析构函数。
c
//myqlabel.h
#ifndef MYQLABEL_H
#define MYQLABEL_H
#include<QLabel> //需要自己手动写头文件
class MyQLabel : public QLabel
{
public:
MyQLabel(QWidget* parent); //构造函数
~MyQLabel(); //析构函数
};
c
#include"myqlabel.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
MyQLabel* label = new MyQLabel(this);
label->setText("hello world");
}
运行结果

当关闭窗口时,终端会打印日志信息

这里出现了乱码,证明我们这里的编码方式出现了问题。但是确实是对象树会帮我们统一进行管理对象,不需要我们自己手动的去释放资源。
字符编码问题
出现了乱码问题,大多数情况下都是编码方式出现了问题。常用的两种编码方式是GBK和utf8,myqlabel.cpp源文件使用的是utf8,如何验证呢?



可以看到,果然是utf8编码格式的,如果显示的是ANSI,那就是GBK编码方式,那就能说明终端一定不是utf8的字符编码格式,所以才会出现乱码。
那我们该如何解决乱码问题呢?是修改源文件的编码方式吗?这样好像不大好,那是修改终端吗?其实也不好,这里有两种解决方式,使用QString,可以帮我们自动处理编码方式。不止是QString,QT也提供了专门用来打印日志的工具,可以自动处理编码方式。
c
//需要包含头文件#include<QDebug>
MyQLabel::~MyQLabel()
{
//std::cout<<"myQlabel 析构"<<std::endl;
qDebug()<<"myQlabel 析构";
}
//qDebug是一个宏,封装了QDebug对象,可以当作cout来使用

qDebug日志打印
后续在QT中,如果想通过打印日志的方式,输出一些调试信息,都优先使用qDebug,虽然cout也行,但是cout对于编码的处理方式不大好,在windows上容易出现乱码的问题(如果是Linux使用QT Creator,一般就没事了,Linux默认的编码一般都是utf8)。
使用qDebug还有一个好处就是方便统一关闭打印调试日志,可以通过编译开关,来实现一键式关闭。