Qt Creator是Qt官方的IDE,这个IDE为Qt编程人员提供了一个完整的开发环境。当然了,这个IDE是用Qt写的,也是免费的。这个IDE真正的编译部分使用了MinGW gcc compiler。也就是说,这个IDE主要的作用是协助开发人员编写代码,并以更加友好的图形界面方式(而不是命令行)使用MinGW。下面我以MS Visual Studio作为参照,讲一些在Windows平台上Qt Creator的使用体会与小技巧。
1. 工程文件与项目组织结构
VC6之前都是使用dsw文件(之后是sln)来管理软件工程的(新版的VC提供dsw转换工具),每个dsw中可以有很多dsp,即项目文件。每个dsp中都可以包含任意多的.h.cpp.rc文件,每个dsp都可以单独编译。可以编译成exe或dll或ocx等等。一个dsw中的所有dsp也可以一起编译,而且各个dsp之间可以设定依存关系。比如一个dsp叫baseui,一个叫myapp。其中baseui将编译成为baseui.dll,而myapp将编译成为myapp.exe。在myapp中需要用到baseui中的某个类或某个资源或某个函数,那么myapp的依存关系中就需要有baseui。设定好依存关系后,每次整体编译之前,baseui就会先于myapp编译,从而保证myapp需要的lib在编译之前就已经具备。
在Qt Creator中,项目的组织文件是pro类型,它并不具备dsw, dsp那样的2级结构。它跟dsw或dsp文件一样,也是机器生成的文本文件。不过在Qt Creator中,你可能经常需要手动去编辑这个文件。下面是一个简单的pro文件:
TARGET = Test112
TEMPLATE = app
SOURCES += main.cpp/
mainwindow.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui
第1行“TARGET”定义了目标文件的名称;
第2行“TEMPLATE”定义了目标文件的类型,app即可执行文件。Lib是库文件(可以使dll,也可以使使用静态链接的库或是plugin);
“SOURCES”里定义了所有的cpp文件;
“HEADERS”里定义了所有的h文件;
“FORMS”里定义了所有的ui文件(可以在Qt Creator中进行可视化编辑的界面类);
这里多说一下,ui文件经过qmake之后会生成ui_开头的一个.h文件,里面由程序自动生成一个新的UI类,类里面把可视化编辑的界面元素都用代码写出来。在ui文件对应的类中,这个自动生成的ui类会被new一个新的实例,用于协助开发人员。
不知道我说明白了没有,就是ui文件会帮助开发人员生成一些界面相关的代码,然而这些代码是以另一个新的类的成员变量及代码的形式被用于原来那个界面类的。(汗啊,我都说累了)我一直不明白为什么Qt Creator不像VC那样直接去修改原有类的代码。难道这个实现起来很困难吗?我打开.ui文件看过,它其实是界面的一个xml文件描述。忘记在哪里看到这种实现有一个优点就是如果程序界面部分写的足够灵活的话,程序升级时如果只涉及到界面,那么可以只下载这个ui文件进行升级即可。这个特性可能会让那些saas软件开发人员欣喜若狂。但对于大部分desktop app开发人员来说,还是有点让人迷惑。好在Qt中有signal/slot可用于widget与界面类(如dialog)之间传递消息,否则这种中间加一层“假父类”的实现方式是在是让人难以接受。
Pro文件说了这么多,足以说明Qt Creator在项目管理与设置上并不是特别友好。与VC(甚至VC6)相比都有较大差距。编辑pro文件使我想起了N年前使用命令行方式编写turbo C程序。呵呵,可能开源软件就是这个范儿?
关于pro文件,还有很多内容需要开发人员去了解。我会专门写个tip。
2. IDE界面
VC的界面很经典,多年未发生根本性的改变(但相信很多老VCer对VC6以后的版本取消Class Wizard仍然耿耿于怀)。
Qt Creator界面比较一般。硬伤是没有类树(Class Tree),这个对于OOP来说非常的不便。由于没有类树,开发人员便不能对类进行相关的编码,这就意味着增加一个member function需要在该类的.h和.cpp文件中手工输入两次函数名称。同时,重载函数时也需比在VC中付出更多的时间。虽然增加一个函数的时间可能只增加5-10秒,但对于刚刚灵感闪现的程序员来说,可能会比较有挫折感。希望后面的版本能够加上。
代码输入界面Qt Creator做得不错,语法着 {MOD}(不光有标准C++的着 {MOD},还有Qt特有关键字的着 {MOD},如SLOT等)和类似VC的intellisense功能(代码自动完成)让人感觉很舒服。我记得前段时间看VC Team的BLOG还有人留言说intellisense很多问题。在我使用Qt Creator的这两个月时间里,还没发现bug。但是我一直觉得Visual Assist的功能做的最专业。使用VA的同学请举手。
3. 编译
在编译速度上,VC全胜。快得不只一点点。当然qmake本身会多占用一些时间,但还是能明显感觉到VC快很多。
在编译代码质量上,我是门外汉,不敢妄下结论。但我感觉Qt生成的exe文件会更大一些,不知是不是为性能做的牺牲。所以TX门写代码时,千万不要图省事,把整个Qt模块(如QtGUI)都include进来。
4. Debug
不得不说,又是VC赢了。Qt Creator不但速度慢,还经常有些莫名其妙的问题。你可能会被要求重新build Debugging Helper。还可能会出现gdb crash。
5. 帮助
MSDN就不多说了。Qt专门有个Qt Assist程序用于提供所有帮助。Qt Creator中本身也有一个help模块。在网络上,Qt central提供forum和wiki。但是,如果编程中遇到问题,那么你就会发现,使用Qt的人比起使用VC的人来少太多了。可能VC中的一些小问题别人早就碰到并在网上公布解决方案了。而Qt中你碰到的问题,可能在网上很难找到答案。使用Qt的TX们,大家还要努力丰富开源社区。
6. 如何选择
如果你只是使用Qt在Windows上开发,可以选择VC2008。Express版本也是免费的。
如果你是要开发Cross-platform的程序,还是应该选择Qt Creator。因为它在Windows, Linux和Mac上都可以运行(MinGW也是Cross-platform的)。所以从平台移植和维护上考虑,可能Qt Creator是个更好的选择。另外,我个人的经历是,从VC6用到2008,经常会碰到VC莫名其妙的退出,有时代码还未保存。而在使用Qt Creator的这段时间里,这种情况从未发生。相信这也从侧面证明了Qt本身是很健壮的。
一些使用Qt Creator的tip
1. 使用network或opengl或sql等模块后编译不通过
在pro文件中写如下语句:QT += network 或 QT += opengl 或 QT += sql
2. 代码自动完成功能区分大小写
在Tools->Options菜单中的Text Editor->Completion中,勾掉“Case-sensitive completion”,这样就不会因为你大小写错了而使整个completion都消失掉。
3. Debug时提示没有debug helper
如下图,在Options菜单中红圈的位置点击Rebuild。
4. Qrc中增加了图片,但是在程序中用不了
Qrc文件中可以增加Qt程序使用的资源文件。这些文件会被编译到exe文件中。增加资源时需要先增加前缀prefix。看看你的prefix写的对不对。如果前缀是“/”那么一个典型的图片文件路径可能是“:/Resources/Images/aaa.png”。另外,在qrc中,文件名和路径名是区分大小写的。我曾经在这里卡了好几个小时,最后都怀疑Qt Creator是不是“水货”了。
5. Qt Creator在Windows系统中,怎样链接VC生成的动态链接库
这个问题曾经困扰了我一整天。我想的是按照VC中的方法,增加include文件,增加lib文件,然后编译即可。谁知链接时总是出现问题。提示是undefined reference to XXXXX。查了手册和网络,原来这是mingw用户在windows上经常遇到的问题,而且好像至今没有完美的解决方案。这个错误的起因是因为VC生成lib的_stdcall函数名与mingw生成的不一致。一种解决方案是使用libdll等工具生成新的用于mingw的lib,另一种解决方案是把代码全拿过来重新编译(汗)。
最后我也不知道为什么自己试出来一个新的方法,这个方法尚未从技术上找到原因。也未经过广泛的测试。有兴趣的TX可以试试。
如果你要链接到一个abc.lib文件,头文件是abc.h,动态链接库是abc.dll。那么在pro文件中先加入下面一行
INCLUDEPATH += D:/Qt/include
INCLUDEPATH是一个编译变量,存储了所有包含include文件的路径,这个目录下保存了abc.h文件。然后再加入下面一行:
LIBS += D:/Qt/bin/abc.dll
LIBS也是一个编译变量,存储了所有需要链接的库文件。看清楚了,不是“abc.lib”哦,是“abc.dll”。神奇吧,这样居然可以链接成功了(lib文件可以删了)。喜欢研究的TX可以研究研究mingw究竟是怎么做的。
6. Qt项目更换文件目录后编译失败
Qt Creator编译时不支持中文路径名。对于带空格的路径,如果你想在pro文件中加入,需要使用$$quote来指定,如:$$quote(C:/mylibs/extra libs/extra.lib)。另外,如果你习惯了Windows下‘/’的话,最好改改你的习惯,在Qt中路径习惯用‘/’。