前言
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代码效果图

image

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> 执行编译的链接步骤,输出可执行文件

image

手动编译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程序打包
      省略
程序编译后执行效果图

image

posted on 2020-11-25 17:43  怪小子  阅读(1360)  评论(0编辑  收藏  举报