前言
Qt 是 C++ 的库,Qt 在 ansi C++ 的基础上进行了一点扩展。 有很大一部分人在学习Qt之前,连C++如何编译似乎都不太清楚。 但本文不对C++编译原理做过多的介绍,只提取Qt部分的编译原理进行解析。
本文中将舍弃IDE或qmake、cmake等工具的束缚,尝试通过几个例子,一步一步从标准 C++ 的编译过渡到 Qt 的编译。
本文涉及的都是最基本的东西,或许可以说,只要你用C++ Qt,不管是通过哪种工具(qmake、cmake、boost.build、qtcreator、vs2008、Eclipse、...),本文的内容都是需要理解的(尽管真正写程序时,我们都不会直接用C++编译器来编译Qt程序)。
注意 >> 由于本地Qt环境版本是 Qt 5.12.8,代码更偏向于该版本,如果你是其他版本,请注意修改。
如果你对命令行比较恐惧,或许愿意先看看资料 GCC新手入门
关键字
- UIC
- RCC
- MOC
Qt之UIC工具
// 简介 >> UIC 是Qt环境下的一个插件,其功能是将*.ui文件扩展为ui_*.h文件,这个文件是C++源代码头文件
// 用法 >> uic *.ui -o ui_*.h
// 输出uiC++源代码文件 >> uic mainwindow.ui -o ui_mainwindow.h
/*
Options:
<-h> -help 显示此帮助并退出
<-v> -version 显示此版本信息
<-d> -dependencies 显示依赖项
<-o> <file> 将输入放到<file>中
<-tr> <func> 对i18n使用func()
<-p> -no-protection 禁用输出文件的头保护
<-n> -no-implicit-includes 禁用为uic生成的窗体生成#include指令
<-g> <name> 更改生成器
*/
Qt之RCC工具
// 简介 >> RCC 是Qt环境下的一个插件,其功能是将*.qrc文件扩展为qrc_*.cpp文件,这个文件是将所有导入到QRC文件的资源扩展为数据并将其存放到静态区。
// 所以这些图片资源是编译到exe(可执行文件),这样软件不会因为外部资源的缺失造成软件界面的异常。有效的提高用户体验度。
// 注意 >> 一般的较小的软件资源可以使用QRC的形式来添加到软件,这将提高软件的存活性,健壮性。
// 用法 >> rcc [name] [*.qrc] -o [qrc_*.cpp]
// 输出 qrc C++源代码文件 >> rcc mainwindow mainwindow.qrc -o qrc_mainwindow.cpp
/*
Options:
-o file 将输出写入文件而不是stdout
-name name 创建名为的外部初始化函数
-threshold level 压缩文件的阈值
-compress level 按级别压缩输入文件
-root path 用根路径作为资源访问路径的前缀
-no-compress 禁用所有压缩
-binary 输出二进制文件以用作动态资源
-namespace 关闭命名空间宏,不会生成 QT_BEGIN_NAMESPACE | QT_END_NAMESPACE
作用域控制宏
-project 输出包含所有
当前目录中的文件
-version 显示版本
-help 显示帮助
*/
QRC转换CPP代码效果图
Qt之MOC工具
// 简介 >> MOC 是Qt环境下的一个插件,其功能是将 Qt 相关的内核代码扩展成CPP源代码
// 用法 >> moc [options] <header-file>
// 输出 moc C++源代码文件 >> moc mainwindow.h -o moc_mainwindow.cpp
Options:
-o<file> 将输出写入文件而不是stdout
-I<dir> 将dir添加到头文件的include路径
-E 仅预处理;不生成元对象代码
-D<macro>[=<def>] 定义宏,具有可选定义
-U<macro> 取消定义宏
-i 不要生成#include语句
-p<path> 包含文件的路径前缀
-f[<file>] 强制使用#include<file>,可选文件名
-nn 不显示便笺
-nw 不显示警告
@<file> 从文件读取其他选项
-v 显示版本
*/
编译原理实例图
<1> C++没有信号和槽是Qt的特性,及ui库相关的模块,所以Qt会将项目源文件扩展项扩展为 C++ 代码,这样就可以使用 C++的编译器来编译Qt的项目
<1.1> ui 扩展为 ui_*.h
<1.2> qrc 扩展为 qrc_*.cpp
<1.3> 引用了 Qt 的元对象系统头文件扩展为 moc_<file>.cpp
<2> 现在Qt项目中的所有代码都是C++源代码了,这里就可以直接使用C++编译器把源代码编译成二进制文件
<3> 执行编译的链接步骤,输出可执行文件
手动编译Qt项目Gui案例
准备 >> 新建一个默认的 Qt Gui 程序,将其源代码拷贝到准备好的编译目录,有以下文件:
<1> main.cpp
<2> widget.cpp
<3> widget.h
<4> widget.qrc
<5> widget.ui
<6> widget.pro widget.pro.user 删掉,我们用不着
操作步骤:
<1> 新建编译输出目录
mkdir build
cp .../src_dir/*.* .../build/
cd .../build/
<2> 扩展ui文件为C++格式
/opt/Qt5.12.8/5.12.8/gcc_64/bin/uic widget.ui -o ui_widget.h
<3> 扩展qrc文件为C++格式
/opt/Qt5.12.8/5.12.8/gcc_64/bin/rcc widget widget.qrc -o qrc_widget.cpp
<4> 扩展widget.h到moc_widget.cpp
/opt/Qt5.12.8/5.12.8/gcc_64/bin/moc widget.h -o moc_widget.cpp
<5> 当前所有的代码都为C++代码了,可以进行编译了
<5.1> 编译main.cpp
g++ -c -pipe -g -std=gnu++11 -Wall -W -D_REENTRANT -fPIC -DQT_DEPRECATED_WARNINGS -DQT_QML_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I. -I/opt/Qt5.12.8/5.12.8/gcc_64/include -I/opt/Qt5.12.8/5.12.8/gcc_64/include/QtWidgets -I/opt/Qt5.12.8/5.12.8/gcc_64/include/QtGui -I/opt/Qt5.12.8/5.12.8/gcc_64/include/QtCore -I. -isystem /usr/include/libdrm -I. -I/opt/Qt5.12.8/5.12.8/gcc_64/mkspecs/linux-g++ -o main.o main.cpp
<5.2> 编译 widget.h
g++ -c -pipe -g -std=gnu++11 -Wall -W -D_REENTRANT -fPIC -DQT_DEPRECATED_WARNINGS -DQT_QML_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I. -I/opt/Qt5.12.8/5.12.8/gcc_64/include -I/opt/Qt5.12.8/5.12.8/gcc_64/include/QtWidgets -I/opt/Qt5.12.8/5.12.8/gcc_64/include/QtGui -I/opt/Qt5.12.8/5.12.8/gcc_64/include/QtCore -I. -isystem /usr/include/libdrm -I. -I/opt/Qt5.12.8/5.12.8/gcc_64/mkspecs/linux-g++ -o widget.o widget.cpp
<5.3> 编译qrc_widget.cpp
g++ -c -pipe -g -std=gnu++11 -Wall -W -D_REENTRANT -fPIC -DQT_DEPRECATED_WARNINGS -DQT_QML_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I. -I/opt/Qt5.12.8/5.12.8/gcc_64/include -I/opt/Qt5.12.8/5.12.8/gcc_64/include/QtWidgets -I/opt/Qt5.12.8/5.12.8/gcc_64/include/QtGui -I/opt/Qt5.12.8/5.12.8/gcc_64/include/QtCore -I. -isystem /usr/include/libdrm -I. -I/opt/Qt5.12.8/5.12.8/gcc_64/mkspecs/linux-g++ -o qrc_widget.o qrc_widget.cpp
<5.4> 编译moc_widget.cpp
g++ -c -pipe -g -std=gnu++11 -Wall -W -D_REENTRANT -fPIC -DQT_DEPRECATED_WARNINGS -DQT_QML_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I. -I/opt/Qt5.12.8/5.12.8/gcc_64/include -I/opt/Qt5.12.8/5.12.8/gcc_64/include/QtWidgets -I/opt/Qt5.12.8/5.12.8/gcc_64/include/QtGui -I/opt/Qt5.12.8/5.12.8/gcc_64/include/QtCore -I. -isystem /usr/include/libdrm -I. -I/opt/Qt5.12.8/5.12.8/gcc_64/mkspecs/linux-g++ -o moc_widget.o moc_widget.cpp
<6> 链接
g++ -Wl,-rpath,/opt/Qt5.12.8/5.12.8/gcc_64/lib -o testting main.o widget.o qrc_widget.o moc_widget.o /opt/Qt5.12.8/5.12.8/gcc_64/lib/libQt5Widgets.so /opt/Qt5.12.8/5.12.8/gcc_64/lib/libQt5Gui.so /opt/Qt5.12.8/5.12.8/gcc_64/lib/libQt5Core.so -lGL -lpthread
<7> Qt程序打包
省略
程序编译后执行效果图
作者:
怪小子
Github:
https://github.com/MrSunHua
邮箱:sh4a01@163.com
本文版权归作者和博客园共有,欢迎转载,如文章有版权冲突或者有更好的见解及建议,还望联系博主讨论并修改。