第03天 使用VS 2019和Qt构建一个命令行程序

视频讲解

今天要学习的案例对应的源代码目录:src/chapter02/ks02_01。本案例不依赖第三方类库。程序运行效果如图2-1所示。

图2-1 第03天案例程序在Windows系统中的运行效果

今天的目标是掌握如下内容。

  • 使用VS 2019、Qt开发命令行程序的最基本方法。
  • 学习Qt项目文件的基本配置。
  • 使用VS 2019的IDE编译、构建程序的方法。
  • 使用命令行编译、构建程序的方法。
  • 将代码传送到Linux上的方法。
  • 在Linux上编译程序的方法。

注意:本案例在运行时虽然不依赖第三方库,但是在编译时需要借助Qt的qmake命令将Qt的项目配置文件(.pro文件)转换成VS 2019可以识别的项目配置文件(.vcxproj文件),因此需要先安装Qt。Qt的安装方法见第2天学习内容。

1.开发应用程序

在用C++进行软件开发时,一般会创建一个项目文件,通过项目文件就可以知道该项目包含哪些源代码文件或资源文件。在C++中,项目文件是Makefile文件。手工编写Makefile文件非常麻烦,而且还涉及非常复杂的编译选项。Qt提供了一种简化手段来生成Makefile文件。它要求开发者提供项目的pro文件,然后使用qmake命令将其转换为Makefile。那么pro文件是什么呢?pro文件是Qt定义的项目配置文件。它是文本格式的文件,采用key =values的语法。比如,项目用到了main.cpp,那就在项目的pro中编写:

     SOURCES +=  main.cpp

其中,SOURCES指示本项目用到的cpp文件列表。其中+=表示在SOURCES原值的基础上添加main.cpp。比如,在pro中可以继续追加cpp文件:

     SOURCES =  main.cpp // SOURCES 的值为 main.cpp
     SOURCES += imp.cpp  // SOURCES 的值为 main.cpp、imp.cpp

这样,项目包含的cpp文件(SOURCES文件)就变成: main.cpp、imp.cpp。如果有多个cpp文件,可以写在main.cpp的后面,比如:

     SOURCES += main.cpp  imp.cpp

但如果这样写,代码的可读性不是很好,这种情况下可使用“\”进行换行。比如:

注意:main.cpp和后面的“\”之间最好加一个空格以增加可读性。

项目中添加头文件时使用HEADERS配置项,用法同SOURCES。比如:

每个Qt项目最终都要生成一个目标程序。为了指示项目的目标程序名称,需要用到TARGET配置项,比如:

     TARGET = ks02_01

这表明该项目生成的目标程序名称为ks02_01。如果它是一个可执行程序,那么在Windows上生成的程序为ks02_01.exe,而在Linux上(或UNIX)上为ks02_01。如果生成的是一个DLL(Dynamic Link Library,动态链接库),那么在Windows上为ks02_01.dll,而在Linux(或UNIX)上可能为libks02_01.so.1.0.0。

以上介绍了pro文件最基本的配置。代码清单2-1是本案例pro文件的完整内容。

代码清单2-1

在代码清单2-1中,TEMPLATE = app表示这是一个EXE项目。如果本项目生成的最终模块是一个DLL,则写成TEMPLATE=lib。因为使用C++语言进行开发,所以写成LANGUAGE = C++。这个项目是一个终端运行程序,即命令行程序,所以写成CONFIG +=console。如果不这样设置,则无法在终端中正常运行(比如,cout的信息无法输出到终端)。如果想进行验证,可以封掉这行配置,方法是在该行配置前加上一个“#”号(输入#时请使用英文、半角,不要用中文)。“#”表明本行是注释,那么Qt就不会把这行当作配置进行解析。封掉某配置项时可以写成:

     #CONFIG += console

最后的三个末尾字母为DIR的用来描述各种路径。

DESTDIR:表示生成的最终目标程序的存放路径。

OBJECTS_DIR:表示程序生成的中间临时文件的存放路径。

MOC_DIR:用来描述moc文件的存放路径(Qt的moc命令生成的临时文件)。该配置项会在后面的章节进行详细说明。

在本案例的pro文件中,这些路径的设置都使用了相对路径的方式,其实一般不推荐这种方式。在后续的案例中将使用环境变量的方式设置这些路径。

注意:Windows系统中的文件和文件夹的名字是不区分大小写的,而在Linux系统中是区分的。比如,file.txt和FILE.txt在Windows中是一个文件,而在Linux中则是两个文件。因此,为了减少不必要的拼写麻烦,建议所有文件名、文件夹名以小写方式命名。

本节的EXE功能很简单,仅输出一行信息:“这是我的一小步,但却是全体程序员的一大步!!!”。具体代码请见代码清单2-2。

代码清单2-2

在代码清单2-2中,为了向终端输出信息,用到了STL库的cout、endl(cout用来向终端输出信息,endl表示换行)。这需要引用<iostream>,所以编写#include <iostream>语句。这是C++的写法,在C中使用#include "iostream.h"的写法。除此之外,在标号①、标号②处,使用using语句引入了cout和endl,这是为了避免引入整个stl命名空间。有的程序员可能会写成:

     using namespace stl; // 不推荐

本书不推荐这样的写法。在涉及命名空间的使用时,应该仅引入所需的内容或者不编写引入命名空间的代码,即直接使用std::cout的写法:

     std::cout << “xxx” << std::endl;

main()函数比较简单,因此不再过多讲解。下面看一下怎么构建这个项目。

2.构建应用程序

现在把pro文件和cpp文件放到同一个目录下,目录名设置为ks02_01。最后,构建(有时也称作编译)项目,以便生成最终的目标程序。可以通过两种方式构建应用程序:使用Qt Creator或者使用VS 2019。

1)使用Qt Creator构建应用程序

启动Qt Creator,选择【文件】|【打开文件或项目】菜单项,会出现【打开文件】对话框,打开ks02_01.pro。然后在图2-2所示界面中单击Configure Project按钮对项目进行配置。

图2-2 Qt Creator项目配置

然后,单击图2-3中的【构建项目】按钮。

当构建成功后,单击图2-3中的【运行】按钮即可启动本案例的程序。

2)使用VS 2019命令行构建应用程序

首先根据构建的应用程序位数(64位/32位),选择对应的VS 2019命令行。关于64位程序与32位程序的含义及区分方法请见本书配套资源中【附录.pdf】中的【32位/64位程序的区分方法】。如果构建64位程序,则选择如图2-4所示的【x64 Native Tools Command Prompt for VS 2019】(适用于VS 2019的x64本机工具命令提示,简称VS 2019的64位命令行);如果构建32位程序,则选择如图2-4所示的【x86 Native Tools Command Prompt for VS 2019】(适用于VS 2019的x86本机工具命令提示,简称VS 2019的32位命令行)。除特殊说明外,本书所有程序均构建成64位。

图2-3 Qt Creator构建项目

图2-4 VS 2019的x64和x86命令提示启动菜单

在VS 2019的64位命令行中,进入项目所在目录,执行如下命令后即可将项目构建成功。

     qmake
     nmake

其中qmake是Qt提供的命令,用来把项目的pro文件转换成C++编译器可以识别的Makefile项目文件。nmake是VS 2019工具提供的命令,用来根据Makefile构建项目。

3)使用VS 2019 IDE开发工具构建应用程序

如果使用VS 2019的IDE开发工具打开该项目,那么首先要生成VS 2019可以识别的项目文件。生成的方法是在VS 2019的64位(或32位,根据具体需要)命令行中,进入本案例所在目录,运行qmake命令。

     qmake  -tp  vc

其中vc表示生成Visual Studio可以识别的工程文件,-tp表示根据pro文件中TEMPLATE参数的取值生成工程文件。这样就可以生成名为ks02_01.vcxproj的项目文件。以vcxproj为后缀的文件是VS 2019可以识别的项目文件。然后,在开始菜单中选择Visual Studio 2019菜单项启动VS 2019(见图2-5)。

图2-5 VS 2019启动菜单项

启动VS 2019后,选择【文件】|【打开】|【项目/解决方案】菜单项,打开ks02_01.vcxproj项目配置文件。打开项目后,选择【生成】|【生成解决方案】菜单项完成项目构建。

3.用UTF-8编码保存源代码文件

为防止项目在不同的平台中编译出错,建议把源代码文件保存为UTF-8格式。本节介绍两种用UTF-8编码格式保存源代码文件的方法。

注意:为保证在Windows、Linux上能构建成功并且正常显示中文,应确保所有“.h”文件、“.cpp”文件使用带BOM的UTF-8格式保存。Qt自身的文件(如“.pro”“.pri”“.qrc”等)应使用普通的UTF-8格式(不带BOM)保存,否则会导致编译错误。

1)使用Windows自带的记事本保存源代码文件(“.h”“.cpp”文件)

在Windows资源管理器中新建一个空白的文本文件,然后用Windows自带的记事本打开该文件。选择【文件】|【另存为】菜单项,会弹出【另存为】对话框,在【编码】处选择【带有BOM的UTF-8】(见图2-6)。

图2-6 另存为UTF-8编码

2)为Qt Creator设置文件编码

运行Qt Creator,选择【工具】|【选项】菜单项(见图2-7)。

图2-7 Qt Creator工具菜单

如图2-8所示,在【选项】对话框中左侧列表框中选择【文本编辑器】选项卡,然后选择【行为】选项卡,将【文件编码】选项区域的【默认编码】设置为UTF-8,将UTF-8 BOM设置为【如果编码是UTF-8则添加】。

图2-8 Qt Creator编码设置

完成配置后,就可以新建文件了。如图2-9所示,选择【文件】|【新建文件或项目】菜单项。在弹出的New File or Project对话框中选择C++,并根据需要选择C++ Source File或者C++ Header File(见图2-10)。

图2-9 Qt Creator新建文件

图2-10 Qt Creator新建C++代码文件

创建完源代码文件后,在文件中输入源代码后保存即可。请务必输入一些代码,否则直接保存空文件可能会导致文件变为GB 2312编码。

如果用Qt Creator打开项目文件(xxx.pro)时提示错误信息“Cannot read xxx/xxx/xxx.pro:Unexpected UTF-8 BOM”,那么可以用NotePad++编辑器打开项目文件,然后执行【编码】|【转为UTF-8编码】,将项目文件保存,然后再用Qt Creator重现打开项目文件即可。NotePad++的下载地址见配套资源中【资源下载.pdf】文档中【NotePad++网址】。

视频讲解

4.如何把程序传输到Linux并进行编译、运行

下面要学习的案例对应的源代码目录:src/chapter02/ks02_01。本案例不依赖第三方类库。程序运行效果如图2-11所示。

图2-11 Linux运行效果

当需要在Linux上构建、调试、运行程序时,首先需要把源代码传送到Linux机器。下面介绍怎样把项目的源代码传送到Linux上。可以使用FTP工具传送文件到Linux。如果传输多个项目,可以考虑在Windows上使用压缩工具(如7-Zip)将项目源代码打包成zip格式的文件,然后使用FTP工具将压缩包传送到Linux上解压后进行构建。常见的FTP工具有Xftp、FileZilla、FlashFXP等。这里以Xftp为例进行介绍,这几款FTP工具的网址见配套资源中【资源下载.pdf】文档中【FTP工具】。Xftp工具属于Xmanager套件。要使用Xftp,应先启动Xmanager,如图2-12所示。使用Xftp时,首先应创建到Linux主机的Xftp会话,如图2-13所示。

图2-12 启动Xftp的入口

图2-13 创建Xftp会话的菜单

单击【Xftp会话】后,会弹出如图2-14所示的配置界面。在该界面中,配置【名称】【主机】【协议】【用户名】【密码】。其中【名称】用来区分不同的主机连接,【主机】表示连接的Linux主机的IP地址,【协议】一般选择【SFTP】协议(也可以根据情况选择【FTP】协议),【用户名】【密码】用来登录Linux主机。如果希望在建立连接后可以默认打开本地、远程目录,可以在【选项】页面中配置【启动文件夹】中的【本地文件夹】和【远程文件夹】,如图2-15所示。

图2-14 Xftp配置界面

图2-15 配置Xftp的启动文件夹

完成配置后,就可以在Xftp分支中或右侧视图中看到配置好的Xftp会话列表,如图2-16所示。可以双击Xftp会话列表中的会话,从而与Linux真正建立会话连接。成功建立连接的Xftp会话如图2-17所示,其中左侧为本机、右侧为Linux主机,可以在本机、Linux主机之间通过拖放或者双击的方式传输文件。有一点需要注意,Windows上的文本文件与Linux上的文本文件的换行符不一致,因此需要进行配置,以便把文本文件传送到Linux后可以将文本文件的换行符自动替换为Linux格式。在建立会话后,通过选择Xftp的【工具】|【选项】|【传输】,可以配置【ASCII扩展名】,如图2-18所示。

图2-16 Xftp会话列表

图2-17 成功建立连接的Xftp会话

单击【ASCII扩展名】按钮后,会弹出图2-19所示界面。在该界面中,可以配置文件的扩展名(即文件后缀)。以列表中的字符作为后缀的文件将被认为是文本文件,否则将被认为是二进制文件。文本文件在Windows系统与Linux系统中的换行符不同,在Windows中为CR+LF(回车+换行),而在Linux中为LF(换行)。Xftp在传输文本文件时将自动根据目标系统转换文件的换行符。

图2-18  传输选项配置界面

图2-19 【ASCII扩展名】配置界面

当文件被传送到Linux机器后,可以在Linux上启动终端,然后使用unzip命令对压缩包进行解压操作。比如,解压缩src.zip时可以输入如下命令。

     unzip  -x  src.zip

当文件比较少时,可以不压缩,直接利用Xftp把文件夹或文件从Windows复制到Linux。把项目代码传输到Linux之后,可以使用QtCreator或者终端对项目进行编译、构建。用QtCreator构建项目的方法在第3天学习内容中已经介绍。使用终端方式构建项目时,需要先配置系统环境变量,然后进入项目所在目录,并执行如下命令。

     qmake
     make

执行qmake后生成Makefile。make是Linux上的工具,用来根据Makefile构建项目。