Qt介绍

Qt是跨平台的开发库,主要是开发图形用户界面(Graphical User Interface,GUI)应用程序,当然也可以开发非图形的命令行(Command User Interface,CUI)应用程序。 Qt支持众多的操作系统平台,如通用操作系统Windows、Linux、Unix,智能手机系统Android、iOS、WinPhone,嵌入式系统QNX、VxWorks等等,应用广泛。当然Qt库本身包含的功能模块也日益丰富,一直有新模块和第三方模块扩充。除了与操作系统底层结合特别紧密的,如驱动开发,需要利用操作系统本身的函数库实现之外,其他大部分的应用程序开发都可以用Qt实现的。Qt本身是纯c++开发的,此外Qt还存在Python、Ruby、Perl等脚本语言的绑定,也可以使用脚本语言开发基于Qt的程序。
在Qt4以前的时代主流的是传统部件(或叫控件)编程,所用的语言一般是c++。Qt5诞生之时,正是手机移动设备蓬勃发展的时候,而传统的c++部件编写的界面对手机应用程序不是很方便,比如手机屏幕显示需要满足随意翻转功能,而这在传统桌面程序里基本遇不到。为了适应手机移动应用开发,Qt5将QML 脚本编程提到与传统c++部件编程相同的高度,力推QML界面编程,当然QML主要用于手机移动应用程序。QML包含大量使用手机移动设备的功能模块,比如基本部件(QtQuick模块)、GPS定位、渲染特效、蓝牙、NFC、WebkKit等等。
简单地说,如果是传统桌面应用程序,使用c++部件开发就足够,如果是手机移动应用开发,QML是更好的选择。

关于Qt的下载,可以参考Qt维基网站,其中会显示最新的正式版、LTS版、正在开发中的版本等详尽的版本信息。

Qt开发环境的目录结构

下面以Linux环境下Qt5.4版本为例介绍Qt开发环境的目录结构,其他版本也可以此作为参考(涉及windows的内容默认是minGW环境)。
因为Linux系统自带编译生成工具,因此Qt开发环境在Linux系统里所需安装的工具和依赖的库文件比在Windows里少一些。在Linux系统里Qt安装的开发环境大致分为两部分:

  • Qt类库的路径为

~/Qt5.4.0/5.4/gcc_64

  • QtCreator集成开发环境的路径为

~/Qt5.4.0/Tools/QtCreator

如果安装了Qt类库的源代码,则位于~/Qt5.4.0/5.4/Src目录里面(波浪号~是指当前用户主文件夹,如用户ABCDE的主文件夹为/home/ABCDE,如果是其他用户想用该用户目录下的Qt则应该指明该用户家目录的路径,在Windows或是MS-DOS下用户没有宿主目录,那么波浪号所指的目录则根据环境变量HOME而定)。如果是windows系统还要额外安装编译工具集,路径为C:\Qt\Qt5.4.0\Tools\mingw491_32,这个是MinGW工具集本身,拥有g++、ld、ar、mingw32-make等等编译链接生成工具。(如果是Visual Studio版本的Qt开发环境,可以参考vs版本安装教程)

Linux系统里Qt开发环境整体的目录树绘制如下:

Docs里的是帮助文档,需要Qt Assistant来查阅,Examples是例子代码,最后的MaintenanceTool是管理工具,如果是用离线包安装的,那只能用它删除Qt开发环境,如果是在线安装方式,还可以用它管理Qt开发环境的组件和升级组件。
进一步再细分查看Qt类库的目录QTDIR,得到下图Qt类库目录树:

Qt工具集介绍

Qt官方的开发环境安装包里有自己专门的开发工具。其中qmake是Qt开发最核心的工具,可以生成Qt项目.pro文件,也可以自动生成项目的Makefile文件。项目(或者叫工程)是指为实现某个相对独立功能的程序代码合集,这些代码不单单是放在一块,而是有相互之间的关联性,并且有专门负责管理该项目的项目文件,比如Qt使用.pro文件管理项目,VC++则使用.vcproj作为项目文件。集成开发环境通常都是依据项目文件(.pro/.vcproj)管理和构建项目。

常用的Qt开发工具列表如下:

  • qmake:核心的项目构建工具。可以生成跨平台的.pro项目文件,并能依据不同操作系统和编译工具生成相应的Makefile,用于构建可执行程序或链接库。
  • qtcreator:集成开发环境。包含项目生成管理、代码编辑、图形界面可视化编辑、编译生成、程序调试、上下文帮助、版本控制系统集成等众多功能,还支持手机和嵌入式设备的程序生成部署。
  • designer:Qt设计师。专门用于可视化编辑图形用户界面(所见即所得),生成.ui文件用于Qt项目。
  • uic:User Interface Compiler,用户界面编译器。Qt使用XML语法格式的.ui文件定义用户界面,uic根据.ui文件生成用于创建用户界面的c++代码头文件,比如ui_*****.h。
  • moc:Meta-Object Compiler,元对象编译器。moc处理c++头文件的类定义里面的Q_OBJECT宏,它会生成源代码文件,比如moc_*****.cpp,其中包含相应类的元对象代码,元对象代码主要用于实现Qt信号/槽机制、运行时类型定义、动态属性系统。
  • rcc:Resource Compiler,资源文件编译器。负责在项目构建过程中编译.qrc资源文件,将资源嵌入到最终的Qt程序里。
  • assistant:Qt助手。帮助文档浏览查询工具,Qt库所有模块和开发工具的帮助文档、示例代码等都可以检索到,在Qt开发中非常实用。
  • linguist:Qt语言家。代码里用tr()宏包裹的就是可翻译的字符串,开发人员可用lupdate命令生成项目的待翻译字符串文件.ts,用linguist翻译多国语言.ts,翻译完成后用lrelease命令生成.qm文件,然后就可用于多国语言界面显示。
  • qmlscene:在Qt4.x里是用qmlviewer进行QML程序的原型设计和测试,Qt5用qmlscene取代了旧的qmlviewer。新的qmlscene另外还支持Qt5中的新特性scenegraph。

Qt项目的编译

使用g++手动编译并执行Qt程序

一般使用集成开发环境Qt Creator开发程序,用户是不需要关心环境变量之类的设置的,该工具自己会去寻找编译器g++、调试器gdb、生成器make以及系统里的开发库。如果需要手动编译的话,如果系统之前就自带Qt编译工具,那么进入终端直接输入命令进行编译即可。但是如果是新下载的Qt环境,还没有添加环境变量的话,就可以编制脚本来进行环境变量的配置。假设在用户主文件夹新建一个shell脚本qt5env.sh并编辑其中的内容:

  • 设置环境变量QTDIR指示Qt库的位置
  • 添加Qt库的bin目录到PATH变量里
  • 添加Qt库的lib目录到LD_LIBRARY_PATH变量里。

由于这里把QTDIR/bin目录放在了旧的$PATH变量的前面,所以进入shell后会优先使用新安装的Qt库工具集。LD_LIBRARY_PATH变量是类似地设置,LD_LIBRARY_PATH是指定动态链接库的路径,也是优先使用新安装的Qt动态链接库。然后切换到家目录(qt5env.sh所在目录),使用终端工具gnome-terminal(GNOME 桌面环境)或konsole(KDE 桌面环境)启动一个新的终端以便进行编译。
脚本的实际编写大概是这样的:

export QTDIR=~/Qt5.4.0/5.4/gcc_64
export PATH=~/Qt5.4.0/5.4/gcc_64/bin:$PATH
export LD_LIBRARY_PATH=~/Qt5.4.0/5.4/gcc_64/lib:$LD_LIBRARY_PATH
cd ~
konsole  #如果是GNOME桌面环境则用gnome-terminal

接下来就是执行脚本

chmod +x ./qt5env.sh  #使脚本具有执行权限
./qt5env.sh  #执行脚本

下面就可以进行Qt程序的编译了,这里现以一个最简单的helloworld程序为例:

// ~/helloworld.cpp
#include <iostream>
using namespace std;

int main(int argc, char **argv)
{
    cout<<"Hello world!"<<endl;
    return 0;
}

注意项目和代码文件的全路径里不要包含任何中文字符、特殊字符和空格,这些字符对程序编译不方便,并且会导致开发工具找不到文件。
使用g++手动进行编译:

g++ helloworld.cpp -o helloworld
./helloworld

如果在windows系统中可能还存在另外一些问题:直接在MinGW命令行环境可以执行helloworld.exe程序,但是直接在系统点击该helloworld.exe程序无法执行。这是由于helloworld.exe所依赖的一些动态库.dll文件只有在minGW环境里有,系统环境变量是没有的。此时要么是添加环境变量,要么干脆把依赖的.dll文件复制到当前目录(大概是GCC异常处理库libgcc_s_dw2-1.dll和c标准库libstdc-6.dll)。或者可以采用静态链接的方法编译(静态链接库是直接塞入exe中的,删除.lib文件后exe照常能运行,而动态链接是.exe在运行时才链接的):

g++ helloworld.cpp -static -o helloworld

这样生成的.exe要比动态链接方式生成的大非常多,点击该.exe文件可以直接在系统环境中运行。
此外,编译生成的可执行程序通常有两种版本,DeBug和Release版本,即调试和发行版本。

  • Debug版本:代码编写之后,生成的目标程序或库文件通常不会绝对正确,或多或少有些毛病(bug),因此需要进行纠错调试(Debug)。调试过程中需要源代码和二进制目标程序之间一一对应的关系,这样才能定位到错误代码,所以Debug版本的程序是不进行优化的。
  • Release版本:在纠正了发觉到的错误后,需要发布程序用于实际用途,实际应用时强调运行效率高,减少冗余代码,因此会对二进制程序进行大量优化,提升性能。
  • Debug和Release版本程序通常链接的也是各自版本的库文件。

g++默认情况下生成的都是Release版可执行程序,如果希望在可执行程序里加入Debug调试信息以供gdb调试,需要编译时加一个-g选项:

g++ helloworld.cpp -g -o helloworld