我们将 main.cpp 修改如下:
#include <QApplication>
#include <QLabel>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QLabel label("Hello, world");
label.show();
return app.exec();
}
点击 Qt Creater 左侧下面的绿色三角按钮即可运行(这里一共有三个按钮,从上到下分别是“运行”、“调试”和“构建”)。如果没有错误的话,就会看到运行结果.
前两行是 C++ 的 include 语句,这里我们引入的是QApplication
以及QLabel
这两个类。main()
函数中第一句是创建一个QApplication
类的实例。对于 Qt 程序来说,main()
函数一般以创建 application 对象(GUI 程序是QApplication
,非 GUI 程序是QCoreApplication
。QApplication
实际上是QCoreApplication
的子类。)开始,后面才是实际业务的代码。这个对象用于管理 Qt 程序的生命周期,开启事件循环,这一切都是必不可少的。在我们创建了QApplication
对象之后,直接创建一个QLabel
对象,构造函数赋值“Hello, world”,当然就是能够在QLabel
上面显示这行文本。最后调用QLabel
的show()
函数将其显示出来。main()
函数最后,调用app.exec()
,开启事件循环。我们现在可以简单地将事件循环理解成一段无限循环。正因为如此,我们在栈上构建了QLabel
对象,却能够一直显示在那里
#include "qttest.h"
#include <QtWidgets/QApplication>
#include <QLabel>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QLabel *label=new QLabel("hello world");
label->show();
return app.exec();
}
答案是,不建议这样做!
首先,按照标准 C++ 来看这段程序。这里存在着内存泄露。当exec()
退出时(也就是事件循环结束的时候。窗口关闭,事件循环就会结束),label 是没办法 delete 的。这就造成了内存泄露。当然,由于程序结束,操作系统会负责回收内存,所以这个问题不会很严重。即便你这样修改了代码再运行,也不会有任何错误。
早期版本的 Qt 可能会有问题(详见本文最后带有删除线的部分,不过豆子也没有测试,只是看到有文章这样介绍),不过在新版本的 Qt 基本不存在问题。在新版本的 Qt 中,app.exec()
的实现机制确定,当最后一个可视组件关闭之后,主事件循环(也就是app.exec()
)才会退出,main()
函数结束(此时会销毁app
)。这意味着,所有可视元素已经都关闭了,也就不存在后文提到的,QPaintDevice
没有QApplication
实例这种情况。另外,如果你是显式关闭了QApplication
实例,例如调用了qApp->quit()
之类的函数,QApplication
的最后一个动作将会是关闭所有窗口。所以,即便在这种情况下,也不会出现类这种问题。由于是在main()
函数中,当main()
函数结束时,操作系统会回收进程所占用的资源,相当于没有内存泄露。不过,这里有一个潜在的问题:操作系统只会粗暴地释放掉所占内存,并不会调用对象的析构函数(这与调用delete
运算符是不同的),所以,很有可能有些资源占用不会被“正确”释放。