小北师兄作品

首发于微信公众号 小北师兄

微信 ID: ncuneupa

由于排版原因,文章可能读起来不太清晰,如果想看更好的排版,可以来我的公众号:小北师兄


大家好,我是你们的小北师兄,由于工作原因,最近师兄在自学 Qt 相关知识,说起来师兄在校期间是研究算法的,一般都是纯 C++ 来实现

当时电脑环境以 Linux 发行版 Ubuntu 为主,到了工作中就转向了 Windows,刚开始确实有一些不太习惯,在 Windows 上配置环境一般比较繁琐,而且有些问题网上还不容易找到

下面进入正题,使用过 Qt 的都知道,我们一般建立一个 Qt 工程,都是在 Qt Creator 中根据向导进行建立,这样比较方便,师兄根据之前使用 CMake / Gcc 的经验,所以对 Qt 的编译过程感兴趣,这样以后出了问题,即使不上网,也可以根据自己的理解,找到问题所在

师兄在网上找到了一个参考资料“Qt Creator 快速入门”,(关注公众号,后台回复 "Qt" ,就可以获取这个资料的电子版及源码)。

这本书就简单介绍了这个编译过程,师兄根据资料上的说明,以及自己的试验过程,对这个问题有了一个更深的理解。

小伙伴们不要失望,师兄写这篇文章可不是直接照搬资料上的内容,相信小伙伴们通读下来绝对会有收获!


文章目录

1 Qt Creator 新建项目及编译过程

2 命令行编译:

1.1 用 Qt 自带环境进行编译

1.2 在 Cmd 终端中直接进行编译

1.3 拓展

本机环境:Windows10 企业版 64 位 + QT5.9.9 + MinGw 5.30 32 位


1 Qt Creator 新建项目及编译过

师兄这里拿出资料上的一个例子(没有 ui 文件的),我们在 Qt Creator 创建一个 Empty qmake project (空项目),然后自己添加 C++ 文件 main.cpp,该源文件内容如下:

#include <QApplication>#include <QDialog>
#include <QLabel>int main(int argc, char **argv) {
QApplication a(argc, argv);
QDialog w;
w.resize(400, 300);
QLabel label(&w);
label.move(120, 120);
label.setText(QObject::tr("Hello"));
w.show();
return a.exec();
}

编辑 .pro 文件,添加 greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 即可,然后编译该程序,可以看到编译输出结果如下图 1 所示

图 1 Qt Creator 编译输出结果

小伙伴请对图片上红色框起来的内容 mingw32-make 留个印象,下面还会用到这个。编译完成后就可直接正常运行。

可以看到,用 Qt Creator 创建项目/编译运行项目非常简单,几步操作下来就可以运行一个程序。


2 命令行编译:

为了了解 Qt Creator 背后为大家做的工作,需要知道如何用命令行编译这个程序。我们先建立一个文件夹 2-2-2,然后将上面写好代码的 main.cpp 原封不动的拷贝到这个文件夹中,目前为止,准备工作完毕,接下来进入正题。

在 Windows 中,需要打开 cmd 这个终端程序(定位到 2-2-2 目录),然后按照如下命令即可编译 Qt 程序,主要步骤如下:

  1. 调用 qmake -project 生成 .pro 文件,在该文件中添加 greaterThan(QT_MAJOR_VERSION, 4): QT += widgets这句话
  2. 调用 qmake 生成 Makefile 文件和 debug / release 目录等等,
  3. 调用 mingw32-make 读取 Makefile 然后对代码进行编译链接(内部调用的是 gcc/g++ 编译器),生成 .exe 文件到 release 目录,默认的是 release 版本,如果想要 debug 版本,可以使用 mingw32-make -f Makefile.Debug 这个命令来代替(下面会说如何知道的)

Note: 如果不知道到 qmake,以及 mingw32-make 都有哪些选项,可以使用 --help 参数来查看,比如 qmake --help ,就会列出该命令一些选项参数介绍。

下面以两种方法进行命令行编译


1.1 用 Qt 自带环境进行编译

在电脑的菜单栏中找到 Qt5.9.9(MinGw 5.3.0 32-bit) 这个终端程序(对应到你自己的 Qt 版本即可,这个是 Qt 的运行环境),然后跳转到你的工作目录中,使用上面的命令即可。

1)打开电脑开始界面选择 Qt5.9.9(MinGw 5.3.0 32-bit) 这个终端程序,如下图 2 所示

图 2 Qt 自带环境终端

2)按照下图 3,图 4 方法进行操作即可

图 3 终端运行命令及结果

这里有两点需要注意:

  1. 在使用 qmake -project 之后,需要在生成的 .pro 文件中进行 Qt 库的包含,比如我这里就需要添加greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 这一行代码。

  2. 黄色画线地方,在这个终端中,前面必须加上 /d 才能跳转到对应的文件夹中,然后再用 qmake -project 即可生成 .pro 文件

继续按照下图 4 方式操作

图 4 终端运行命令及结果

从参考资料上,只说了默认生成 .exe 在 release 文件夹中,没有说明如何生成 debug 版本的 .exe 文件,所以我特意观察了一下 mingw32-make 的输出信息,从上图的红横线部分可以看到 mingw32-make -f Makefile.Release 是读取 Makefile.Release 文件内容进行编译的,结果输出就会进入 release 目录,所以我查看了 mingw32-make 的选项参数,发现 -f 是指定哪个 Makefile 文件的,因此就得出mingw32-make -f Makefile.Debug 会输出到 debug 目录中,经过实验验证了。

之后通过键入如下命令 cd release &&``2-2-2.exe 就可以正常运行程序了

3)我们可以大致看一下 Makefile 内容,如下图 5 所示

图 5 Makefile 文件内容

可以看到 CC CXX 表示用了什么编译器,这里用了 gcc/g++,链接器使用了 g++,等等,从这里都可以看到编译程序需要哪些库以及编译选项


1.2 在 Cmd 终端中直接进行编译

Win + R 输入 cmd 进入终端,跳转到对应文件夹中,然后运行上述命令,但要注意,你必须要配置好系统的 PATH 环境变量才行,比如我自己配置的环境变量如下图 6 所示

图 6 本机系统环境变量配置信息

之后依次运行以下命令即可

qmake -project` 之后修改 .pro 文件,在运行下面命令,`qmake && mingw32-make

cd release && 2-2-2.exe 即可运行程序


**

**

1.3 拓展

如果按照上面的方法来做,相信大家肯定能够成功运行(师兄研究半天才得出的终极结论),但是师兄第一次实验就没有这么幸运了,走了好多弯路,下面师兄就把自己遇到的问题,中间思考过程以及最终结论一一说明

如果你们用过 Qt 开发过界面程序,那么肯定遇到过类似下图的问题:

图 7 遇到的问题

师兄做这个实验也遇到了这个问题,首先,师兄没有使用 Qt 自带的运行环境(哈哈 师兄当时可能是飘了,不过不飘就不会得出上面的终极结论分享给大家了,算了算还是不亏的),就直接打开了 cmd ,然后调用上面 qmake -project ,qmake,mingw32-make 直接一波操作操,心想,肯定可以直接运行了

没想到现实 pia pia pia~,运行 .exe 时就出现了上面的提示,师兄当时就蒙了, QT 自带环境也是在终端运行的啊,我也是在终端运行的啊,我在安装 Qt 的时候也设置了环境变量了,为什么会出现这个问题呢?

想必大家也是跟师兄有着同样的问题,先看一下这个问题,一般引起这个问题都是缺少相应的 dll 结尾的动态链接库,那么好办了,经过我这两天对 Qt 的了解,还真的有一个解决方法,那么就是用 Qt 自带的部署程序 windeployqt ,通过这个程序就可以将一些依赖自动复制到你的文件夹中了,然后在运行就会发现解决了,如图 8 所示

图 8 利用 windeployqt 程序运行结果

图 8 中红色框都是 windeployqt 部署程序生成的,会自动的把你的依赖全部拷贝过来,这种也是将自己的程序,放到没有 Qt 环境的计算机上运行的必备操作。

到这里你以为就完了,不不不,还远远没到,师兄觉得每次命令行编译完成后都要部署一下才能运行太麻烦,说明这个方案不适用于平常的开发,只是一种可选择方案,师兄觉得这个解决方案就用来发布程序就行了。

这又回到了问题的开始,还记得上面师兄说过这么一句,师兄不用 Qt 自带的环境,就在 cmd 命令行中直接键入相应的命令,之后才出现了问题,那咱们就顺藤摸瓜,这个 Qt 环境与我自己直接在命令行中键入命令有什么不一样吗?

打开计算机开始界面,找到 Qt 自带环境的应用程序,如下图 9 所示

图 9 Qt 自带环境探索结果

鼠标右键点击 Qt5.9.9(MinGw 5.3.0 32-bit) 之后点击“开文件位置”,得到如下图 10 所示

图 10 Qt 自带环境探索结果 2

可以看到,这里最终会调用一个 qtenv2.bat 的一个脚本文件,目标是:C:\Windows\System32\cmd.exe /A /Q /K D:\Qt\Qt5.9.9\5.9.9\mingw53_32\bin\qtenv2.bat,(这里多说一句,我们也可以在启动文件夹中仿照这种方法,执行自己的脚本文件,进而配置相应的环境),到对应文件夹下打开该文件,其内容如下图 11 所示:

图 11 qtenv2.bat 内容

可以看到,这里就设置了一下 PATH 的环境变量,师兄之前也在电脑上设置了环境变量,但是好像与这个有点不一样,如下图 12 所示,这是师兄最开始自己电脑的环境变量

图 12 本机最开始的环境变量

经过仔细对比,师兄发现这里多了一个 D:\Qt\Qt5.9.9\Tools\QtCreator\bin; ,且顺序有一点不同,但也仅仅是多了这一个路径而已,没想到会出现这么大的问题,师兄突发奇想,难道真的是多了一个路径才造成这样的结果吗?如果填加了这个路径,那么顺序变化会不会有影响呢?

接下来师兄就做了如下实验,我直接将这个看似多余的路径给删除了,也就是图 6 所示,然后在 cmd 中进行 qmake && mingw32-make 命令,继续运行 2-2-2.exe ,此时就会正常运行

到目前为止,我们找到了问题所在,也就是多出来的这个路径造成的,相信大家到这里还是会有疑问,如果不去掉这个路径还会出现这个问题吗?

师兄又做了下面几个实验,分别设置了 PATH 的环境变量,仅仅顺序不一样,在 cmd 中设置一下环境变量顺序,并且从新执行 qmake mingw32-make 命令,下面仅仅列出路径的顺序及对应结果,具体实验结果图就省略了:

set PATH=D:\Qt\Qt5.9.9\5.9.9\mingw53_32\bin;D:/Qt/Qt5.9.9/Tools/mingw530_32\bin;D:\Qt\Qt5.9.9\Tools\QtCreator\bin;%PATH%

结论:这个可以运行

set PATH=D:/Qt/Qt5.9.9/Tools/mingw530_32\bin;D:\Qt\Qt5.9.9\5.9.9\mingw53_32\bin;D:\Qt\Qt5.9.9\Tools\QtCreator\bin;%PATH%

结论:可以运行,说明 Tools/mingw530_32\ 和 5.9.9\mingw53_32 互换位置也可以,它们两个顺序没有影响

set PATH=D:/Qt/Qt5.9.9/Tools/mingw530_32\bin;D:\Qt\Qt5.9.9\Tools\QtCreator\bin;D:\Qt\Qt5.9.9\5.9.9\mingw53_32\bin;%PATH%

结论:不可以运行,说明 Tools\QtCreator 路径要在 5.9.9\mingw53_32 路径后

set PATH=D:\Qt\Qt5.9.9\5.9.9\mingw53_32\bin;D:\Qt\Qt5.9.9\Tools\QtCreator\bin;D:/Qt/Qt5.9.9/Tools/mingw530_32\bin;%PATH%

结论:可以运行,说明 Tools/mingw530_32 路径可以在 Tools\QtCreator\ 路径后面

综合上面实验及其结果,师兄发现了一个有趣的现象,就是 D:\Qt\Qt5.9.9\5.9.9\mingw53_32\binD:\Qt\Qt5.9.9\Tools\QtCreator\bin 的路径顺序是强相关的。可以没有 D:\Qt\Qt5.9.9\Tools\QtCreator\bin 这个路径,如果在电脑的环境变量中添加了这个路径,那么这个路径 D:\Qt\Qt5.9.9\Tools\QtCreator\bin 必须要在 D:\Qt\Qt5.9.9\5.9.9\mingw53_32\bin 这个路径后面。

相信大家还有一个疑问:D:\Qt\Qt5.9.9\Tools\QtCreator\binD:\Qt\Qt5.9.9\5.9.9\mingw53_32\bin 路径顺序不同是如何造成这个问题的?

师兄结合自己的经验,初步的想了一下,应该是 mingw32-make 在执行过程中,会在系统的 PATH 路径下找到一些东西来执行,恰好,刚刚那两个路径下都有“同样”(或者可代替的)的东西

然后只有 D:\Qt\Qt5.9.9\5.9.9\mingw53_32\bin路径下的东西才可以,师兄也分别查看了这个文件夹,很遗憾,以师兄的能力,还是没能找到这两个路径的哪些东西是"一样的",如果有小伙伴知道这个原因,希望能私信告诉师兄一下。

到这里,这个问题基本上就算解决了,如果小伙伴有其他理解,或者觉得师兄有哪些地方理解有问题,也可以私信师兄哈

喜欢的小伙伴请动动你们可爱的小手,多多点赞!你们的支持为我不断写出干活文章提供源源不断的动力!


推荐阅读

《听说你安装测试 OpenCV 总是不成功?你可能遇到这个坑了!

《反复研究好几遍,我才发现关于 CMake 变量还可以这样理解!

《安装完 Ceres 库,官方文档就能扔掉吗?这些潜在的知识你可能还不会!


来源 | 作者 小北师兄

编辑 | 小北师兄

如需转载,请后台留言

分享给朋友或朋友圈请随意

- END -

觉得不错?右下角「点我、点我、点我」

一个例子让你秒懂 Qt Creator 编译原理的更多相关文章

  1. Qt Creator编译时:cannot open file 'debug\QtGuiEx.exe' File not found

    Qt Creator编译时:cannot open file 'debug\QtGuiEx.exe' File not found 利用Qt Creator编译工程时,出现如题目所示的错误,其中红色部 ...

  2. 嵌入式V3s交叉编译 tslib和QT4.8.7,并使用Qt Creator编译项目

    本文主参考:http://zero.lichee.pro/%E5%BA%94%E7%94%A8/QT_index.html 环境 Ubuntu16 64位 arm-linux-gnueabihf ve ...

  3. QT:提高QT Creator编译速度,配置预编译头Stable.h

    提高QT Creator编译速度,配置预编译头Stable.h QT Creator支持预编译头提高编辑速度,网上有些教程写得不详细,走了弯路,具体实现方法如下. (1)工程.PRO文件加入下面代码 ...

  4. Qt Creator编译问题

    有时候需要自己编译Qt Creator,需要注意的就是qmake版本的问题,比如我用4.8.1和4.8.6同样编译出来的Qt Creator在同样的qtconfig-qt4下所呈现的效果是不一样的. ...

  5. 解决Qt Creator编译输出窗口乱码的问题

    设置环境变量LC_ALL为en_US. 附注:将乱码复制到文本编辑器(如Notepad++)后将编码设置为utf-8,可以看到正确的文字. 看样子是编译输出窗口的编码设置出了问题,或者是gcc的输出编 ...

  6. Qt creator 编译错误 :cannot find file .pro qt

    事实上问题的解决的方法非常easy:就是Qt不支持中文的路径,把源代码的路径所有改成英文就可以解决这个问题. 首先问题发生在我执行网上的样例程序时,又一次构建编译也是出错.提示: Cannot fin ...

  7. 转载-- Qt Creator编译时make: arm-linux-g++: command not found 错误!

    前提是已经配置好交叉编译器,但是qt creator找不到. 解决方法: 修改 /usr/local/Trolltech/QtEmbedded-4.7.0-arm/mkspecs/qws/linux- ...

  8. Qt creator 编译错误:无法解析的外部符号(命令)

    问题来自于:仅仅是在creator 中加入了一个新的DIalog类,并在main(),中实例化并show.就出现例如以下的错误: main.obj:-1: error: LNK2019: 无法解析的外 ...

  9. 一个例子理解c++函数模板的编译

    一.例子 template <typename T> inline void callWithMax(const T& a, const T& b){ f(a > b ...

随机推荐

  1. UI设计师、平面设计师常用的网站大全,初学者必备,大家都在用!

    UI设计师.平面设计师常用的网站大全,初学者必备,大家都在用! 国外的花瓣--Pinterest • The world's catalog of ideas 颜格视觉--app界面设计大全--电商. ...

  2. [刷题] 350 Intersection of Two Arrays

    要求 给定两个数组nums,求两个数组交集 输出结果与元素在两个数组中出现的次数一致 不考虑输出结果的顺序 举例 nums1=[1,2,2,1] nums2=[2,2] 结果:[2,2] 思路 使用m ...

  3. Linux_控制服务与守护进程

    一.systemd 1.systemd简介 1️⃣:systemd是用户空间的第一个应用程序,即/sbin/init 2️⃣:init程序的类型: SysV风格:init(centos5),实现系统初 ...

  4. win10 中安装 JDK8 以及环境配置

    下载和安装 JDK8 下载 下载地址:https://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.html 安装 直接双 ...

  5. Redis()- 布隆过滤器

    一.布隆过滤器 布隆过滤器:一种数据结构.由二进制数组(很长的二进制向量)组成的.布隆过滤器可以用于检索一个元素是否在一个集合中.它的优点是空间效率和查询时间都比一般的算法要好的多,缺点是有一定的误识 ...

  6. RabbitMQ(1)学习目标

    一:安装,专业术语,简单队列,工作队列,发布/订阅队列,路由队列,主题队列,RPC队列,事务,确认模式,SpringAMQP 二:什么是MQ? MQ就是消息队列,是一种进程间通信或同一进程的不同线程间 ...

  7. Go基础结构与类型02---使用iota定义常量组

    package main import "fmt" /*const ( USA = 0 China = 1 Russia = 2 Britain = 3 France = 4 )* ...

  8. Scrapy中的错误

    TabError: Inconsistent use of tabs and spaces in indentation 需要将  .py  文件中的使用 tab 做的空格符删掉,打成空格符.任何一个 ...

  9. Structured Streaming编程 Programming Guide

    Structured Streaming编程 Programming Guide Overview Quick Example Programming Model Basic Concepts Han ...

  10. 使用ONNX将模型转移至Caffe2和移动端

    使用ONNX将模型转移至Caffe2和移动端 本文介绍如何使用 ONNX 将 PyTorch 中定义的模型转换为 ONNX 格式,然后将其加载到 Caffe2 中.一旦进入 Caffe2, 就可以运行 ...