一个稍微复杂的Qt程序

第一个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++:

  • C++ 在C语言的基础上发展而来,C++ 扩展了C语言的语法,早期的 C++ 代码都是先被转换为C语言代码,再使用C语言编译器编译。
  • Qt 是基于 C++ 的,但是它对 C++ 的语法进行了扩展(比如信号和槽机制、内省机制等),并增加了一些关键字(例如 signals、slots、emit 等),在真正编译之前,扩展语法先被转换成 C++ 代码(通过 moc 工具),然后再使用 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("C语言中文网", 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 工具的使用。下面逐步介绍编译链接本节程序的过程。

1) 进入文件夹

打开 Qt 命令行工具,进入代码所在文件夹:

cd /d D:/QtDemo

2) 使用 moc 工具

使用 moc 工具生成 MyMainWindow 类的元对象系统代码文件 moc_MyMainWindow.cpp :

moc MyMainWindow.h -o moc_MyMainWindow.cpp

moc 工具会搜索头文件 MyMainWindow.h 里面所有的 Q_OBJECT 宏,并生成相应的元对象系统实际源代码,输出保存为 moc_MyMainWindow.cpp 文件。

3) 编译和链接 .cpp 文件

加上刚才手动编写的 MyMainWindow.cpp 和 main.cpp,我们总共要编译三个 C++ 源码文件:

g++  moc_MyMainWindow.cpp MyMainWindow.cpp main.cpp  -std=c++0x  -I"D:/Qt/5.9/mingw53_32/include"  -L"D:/Qt/5.9/mingw53_32/lib"  -lQt5Core -lQt5Gui -lQt5Widgets  -o main

4) 运行 main.exe

生成 main.exe 之后,在 Qt 命令行工具里输入main.exe命令就可以执行该程序,看到显示的效果。

生成main.exe的整个流程
生成 main.exe 的整个流程

原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/22438.html

(0)
上一篇 2021年7月20日
下一篇 2021年7月20日

相关推荐

发表回复

登录后才能评论