通过 VS 来开发 Qt 项目的过程中,整个Qt项目的编译需要如下几个过程:
Uic
----> Rcc
----> Moc
----> 预处理
-----> 编译
-----> 汇编
-----> 链接
对比普通的 C++ 项目,Qt 多了 Uic
----> Rcc
----> Moc
这三步。
现在对 QT 项目所多出的三个编译过程进行分析:
一、Uic
:Qt User Interface Compiler
用户界面编译功能,uic.exe
首先需要将Qt项目中的所有 .ui
文件都编译成 ui_%(Filename).h 的C++文件。默认生成在 .\GeneratedFiles\
目录下。该项的具体配置如下图所示
后续在其它的文件中使用UI控件,都可以通过包含对应的头文件: #include "ui_%(Filename).h"
来进行。
【注】可以单独对某一个 .ui
文件进行编译生成对应的 ui_%(Filename).h
文件,如下图,选中对应的 .ui 文件进行编译即可:
二、 Rcc
:Qt Resource Compiler
然后对 Qt 项目的资源文件,即 .qrc
文件进行编译。该文件主要为项目的图片、Icon、logo等内容,通过 rcc.exe 程序将其编译成 qrc_%(Filename).cpp。对应项的默认配置如下图:
三、Moc
:Qt Meta-Object Compiler
1、 Qt 元对象编译器程序 moc.exe
,该程序的功能是将Qt 项目中包含有 Q_OBJECT
宏的类 编译成对应的 moc_%(Filename).cpp 文件,默认生成的路径为: .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp
。
2、调用 moc.exe
来编译的条件
并不是所有的文件都需要调用 moc.exe
来进行编译,只有当一个类中包含了Qt 元对象宏 Q_OBJECT
时,才会自动出触发 moc.exe
对包含该类的文件进行处理。因为当类中包含了Qt 元对象宏 Q_OBJECT
时,表明该类需要使用 Qt 的元对象系统,以实现信号和槽、动态属性等Qt相关的特性。所以需要使用 moc.exe
来将包含该类的源文件进行处理,并生成对应的源代码文件,即moc_%(Filename).cpp
。
如果一个文件中的所有类都没有包含 Q_OBJECT
宏时,则该文件就不会被 moc.exe
处理,也不会生成对应的 moc_%(Filename).cpp
文件。
3、 元对象编译器对应的默认配置如下所示:
几个重要的配置说明如下:
Execution Description
:moc编译每个对应的文件的时候都会输出:Moc'ing %(Identity)...Output File
:moc 处理后生成的文件,默认路径为:.\GeneratedFiles$(ConfigurationName)\moc_%(Filename).cppInclude Path
:moc 在编译的时候需要用到的文件所在路径,一般保持默认即可,如果有调整上面的生成文件路径或需要新增其它的文件,此时需要手动添加。Macro Definitions
:moc 编译过程中使用到的宏,此处定义的宏一般保持默认,不做修改。但是在这里定义的宏,不能被后面的C++编译时使用。C++编译使用的宏需要定义在C/C++
--->Preprocessor
--->Preprocessor Definitions
中。而 C/C++ 的Preprocessor Definitions
中定义的宏会被 moc编译器所继承,如下图,所以在C/C++
--->Preprocessor
--->Preprocessor Definitions
中定义的宏也会在 moc 编译器中起作用。[如果在 C/C++ 对应的预处理器中定义的宏没有在 moc 编译过程中生效,则有一种情况是条件编译中 moc.exe 还未起作用前已经执行了条件编译的判断。此情况需要在 moc.exe 宏定义处或对应的文件起始位置定义对应的宏来解决该问题。]
四、C++ 代码的编译
Qt 项目中的各文件经过以上过程的处理之后,各自会生成对应的 .h
或 .cpp
文件。然后整个项目才能被当作普通的C++项目来通过对应的C++编译器进行编译,经过 预处理
-----> 编译
-----> 汇编
-----> 链接
等过程,最终生成库文件或可执行文件。