《第一个Qt程序》中使用 MainWindow 作为主界面,内置一个 QLabel 控件,所有代码都写在 main() 函数内部。本节我们将主要代码封装到一个类的内部,然后在 main() 函数中创建该类的对象,这貌似更加符合 C++ 规范。
我们在 D:\QtDemo 文件夹创建三个代码文件,分别是 MyMainWindow.h、MyMainWindow.cpp 和 main.cpp,各个文件的具体代码如下所示。
1) MyMainWindow.h 文件代码:
#ifndef MYMAINWINDOW_H
#define MYMAINWINDOW_H
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QLabel>
class MyMainWindow : public QMainWindow
{
Q_OBJECT
public:
MyMainWindow();
~MyMainWindow();
private:
QLabel *m_pLabel;
};
#endif
MYMAINWINDOW_H 可以防止头文件被重复包含,不了解的读者请猛击《防止C语言头文件被重复包含》。
Q_OBJECT 是一个宏,这种写法对初学者来说是非常陌生的,它是 Qt 自己的语法扩展。Qt 的这种做法像极了早期的 C++:
Qt 想要的功能 C++ 没有,怎么办?那就自己上,亲自实现这个功能!为了支持这些扩展功能,Qt 甚至实现了一个微型编译器——元对象编译器(Meta-Object Compiler, moc)。
C++ 为了保持程序运行的高效性,仅通过 RTTI(Run-Time Type Information,运行时类型识别)提供了非常简陋的内省机制,几乎没有用武之地。Qt 抛弃了 C++ 自带的内省机制,另起炉灶,创造了更加强大的元对象(meta object)系统,以此来支持完整的内省机制。
Q_OBJECT 宏就声明了 Qt 元对象系统必须的函数和成员变量,之后我们会用 moc 工具生成元对象系统的实体函数代码。继承 Qt 类时建议在类声明的开头添加 Q_OBJECT 宏,否则有时会出现莫名其妙的错误;如果你使用了信号和槽机制,Q_OBJECT 宏就是必须添加的,因为信号和槽依赖于元对象系统。
2) MyMainWindow.cpp 文件代码:
#include "MyMainWindow.h"
MyMainWindow::MyMainWindow(): QMainWindow(){
this -> setWindowTitle("MyMainWindow演示"); //设置标题
this -> resize(360, 140); //设置客户区大小
m_pLabel = new QLabel("城东书院", this);
m_pLabel -> setGeometry(130, 50, 160, 30); //设置Label控件的几何尺寸
}
MyMainWindow::~MyMainWindow(){
delete m_pLabel;
m_pLabel = NULL;
}
该源文件里只有一个构造函数和一个析构函数。注意析构函数,它删除之前 new 的标签控件对象,并把指针设置为 NULL。
3) main.cpp 文件代码:
#include <QtWidgets/QApplication>
#include "MyMainWindow.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MyMainWindow w;
w.show();
return app.exec();
}
main 函数还是一如既往的简单,由于使用自定义的 MyMainWindow 作为主窗口类,所以是包含了 MyMainWindow.h 和 QApplication 两个头文件。
需要手工编写的代码就这些,接下来的任务就是如何编译生成可执行程序了。
前面提到 Qt 元对象系统,Qt 是基于 C++ 开发的,而 C++ 本身并没有元对象系统。元对象系统是 Qt 专门为 C++ 做的扩展功能,用于支持非常强大的信号/槽机制、内省机制等,后面我们会详细讲解,本节我们重点学习 moc 工具的使用。下面逐步介绍编译链接本节程序的过程。
打开 Qt 命令行工具,进入代码所在文件夹:
使用 moc 工具生成 MyMainWindow 类的元对象系统代码文件 moc_MyMainWindow.cpp :
moc 工具会搜索头文件 MyMainWindow.h 里面所有的 Q_OBJECT 宏,并生成相应的元对象系统实际源代码,输出保存为 moc_MyMainWindow.cpp 文件。
加上刚才手动编写的 MyMainWindow.cpp 和 main.cpp,我们总共要编译三个 C++ 源码文件:
生成 main.exe 之后,在 Qt 命令行工具里输入main.exe命令就可以执行该程序,看到显示的效果。