写在文前
此系列为豆子Qt学习之路2的读书笔记,记录下自己学习Qt的新手历程。
一、Qt简介
完整的C++应用程序框架
常见的C++开发框架有很多,比如STL,Boost,VCL,Ultimate++,这些都支持跨平台。不同的是,Qt不仅仅是一个C++界面库,它在实现了一套基于C++反射的基础上,包含了网络、数据库、多媒体、测试框架、国际化工具、打包部署模块、WebKit等。所以可以分模块地去了解Qt。
跨平台
Qt不仅仅能够运行在桌面环境中,还可以运行在嵌入式平台以及手机平台。
优缺点
- Qt语法类似Java的Swing;使用信号槽(signal/slot)机制,十分清晰;
- 这种机制带来的后果是需要使用Qt的 moc 对程序进行预处理,才能够再使用标准的 make 或者 nmake 进行正常的编译;
- 信号槽的调用要比普通的函数调用慢大约一个数量级Qt4文档中说明该数据,但Qt5 尚未有官方说明)。
- Qt的界面也不是原生风格的,尽管Qt使用 style 机制十分巧妙地模拟了原生界面。
开源
现在Qt的开源版本使用的是 GPLv3 以及 LGPL 协议。这意味着,你可以将Qt作为一个库连接到一个闭源软件里面。
二、运行第一个Qt
Qt官网(http://www.qt.io/download/)直接下载,我下的时候是Qt5.4,安装过程和一般软件无异,自带IDE Qt Creator。
- 打开Qt Creator,给大家截个图,其他没说的用到再介绍。
- 文件->新建文件或项目->Application->Qt Widgets,点choose确定。
- 接下来就是设置项目名称、路径,下一步默认Kits,直接点下一步。
- 出现选择基类,QMainWindow和QDialog都是继承自QWidget。QWidget类是所有用户界面对象的基类,QMainWindow 类提供一个有菜单条、锚接窗口(例如工具条)和一个状态条的主应用程序窗口,QDialog类是对话框窗口的基类。反正新手,随便选个QMainWindow玩玩。
- 下一步是项目管理,添加为子项目,选择版本控制系统,这个可以自己选择。最后点完成。
- 可以看到,Qt Creator 帮助我们在 HelloWorld 项目文件夹下生成了四个文件:main.cpp,mainwindow.cpp,mainwindow.h 和 HelloWorld.pro。pro 文件就是 Qt 工程文件(project file),由 qmake 处理,生成 make 程序所需要的 makefile;main.cpp 里面就是一个main函数,作为应用程序的入口函数;其他两个文件就是先前我们曾经指定的文件名的文件。
- 点击 Qt Creater 左侧下面的绿色三角按钮即可运行,我们来看下main.cpp的代码。
main()函数中第一句是创建一个QApplication类的实例。对于 Qt 程序来说,main()函数一般以创建 application 对象(GUI 程序是QApplication,非 GUI 程序是QCoreApplication。QApplication实际上是QCoreApplication的子类。)开始,后面才是实际业务的代码。这个对象用于管理 Qt 程序的生命周期,开启事件循环,这一切都是必不可少的。
之后直接创建一个MainWindow窗口,调用show()函数将其显示出来。
main()函数最后,调用app.exec(),开启事件循环。我们现在可以简单地将事件循环理解成一段无限循环。正因为如此,我们在栈上构建了MainWindow窗口,却能够一直显示在那里(试想,如果不是无限循环,main()函数立刻会退出,MainWindow当然也就直接析构了)。
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
最后多说下qt经常遇到的一个bug。刚才的代码里有一句
MainWindow w;
w.show();
MainWindow *w = new MainWindow ;
w->show();
这两者的区别:
在C++中生成对象有两种方法,一种是直接用类对象(在内存的stack中),另一种是声明类指针然后new一下(在内存的heap中)。对于前者,在作用范围结束时系统会回收资源,对于后者需要程序员手动回收。
在Qt的Gui编程中,经常会用到QWidget和其子类作为父控件来显示,其上添加有若干控件。在关闭QWidget及其子类窗口时需销毁窗口。
如果是在是定义在stack上,在构造函数中增加:setAttribute(Qt::WA_DeleteOnClose) 以后,会在关闭时出现异常,因为当退出main方法时,会自动销毁窗口,而setAttribute方法会使得Qt再次销毁窗口,造成二次delete,产生报错。
如果定义在heap上,在关闭时main方法不会自动销毁,而Qt会根据setAttribute设置销毁。不会报错。