• 11675阅读
  • 23回复

[转载]将某个Qt4项目升级到Qt5遇到的问题 [复制链接]

上一主题 下一主题
离线XChinux
 

只看楼主 倒序阅读 楼主  发表于: 2013-02-02
— 本帖被 XChinux 执行加亮操作(2013-02-28) —
原文:http://hi.baidu.com/xchinux/item/9044d8ce986accbb0d0a7b87
晚上花了4个小时,将以前的一个项目从Qt 4.8.4-MinGW升级到了Qt5.0.1-MinGW。

该Qt4项目以前是使用Qt4.7.4 MSVC2008开发的,因为使用到了OWC10(Office Web Components),使用MSVC编译器的话无法正常升级到Qt4.8.x和Qt5,于是将编译器转成了MinGW4.7,Qt升级到了4.8.4。今天Qt 5.0.1-MinGW预编译版本发布了,于是就拿它练手,将它升级到Qt5,以减少系统中存在的多个Qt版本 。遇到的问题如下:


1.  由于Qt5将大部分桌面部件移到了Qt Widgets模块中,所以在.pro中要增加下面一行
QT += widgets


2. 程序中使用了OWC10,用到了ActiveQt,原来的做法是在.pro中加CONFIG += qaxcontainer,现在需要改成
QT += axcontainer
当然了,原来的CONFIG += qaxcontainer也将去除

3. 为了充分使用C++11特性,在.pro中加下面一行
CONFIG += c++11

4. 在源文件中,凡是涉及到原QtGui中可视部件的,全要修改头文件引用,或者增加QtWidgets头文件,比如:
#include <QtGui/QPushButton>  要改成  #include <QPushButton>  或者  #include <QtWidgets/QPushButton>
在以前使用#include <QtGui>的地方,要加上 #include <QtWidgets>

5. 由于Qt5去除了QTextCodec::setCodecForCStrings()函数,所以在涉及到在cpp中直接写汉字的情况,有如下两种修改方法:
a)  如果以前的源文件编码是GBK的,则需要使用QString::fromLocal8Bit()函数将原来的汉字括起来;或者直接将源文件编码转换成UTF-8的(缺点是MSVC编译器不能方便的使用了)。我使用了使用QString::fromLocal8Bit()来调用的方式(当然了,另写便捷函数或宏来处理)
b) 如果以前的源文件编码是UTF-8的,则什么都不用动。

6. 以前使用QDesktopServices::storageLocation(QDesktopServices::xxxx)来获取一些系统目录,现在则要改成
QStandardPaths::writableLocation(QStandardPaths::xxxx)


7. 以前调用QFileDialog::getSaveFileName()时,如果在Windows下使用Native Dialog形式指定文件名,则能正常显示,如今Qt5不能正常显示文件名。所以将它的后两个参数加上了,即QFileDialog::getSaveFileName(xxx, xxx, xxx, xxx, 0, QFileDialog::DontUseNativeDialog),这样就正常了,只是它的对话框不是系统形式的,暂且将就吧。

8. 还有,Qt5解决了ui_qaxselect.h文件的问题。在Qt4时代,使用ActiveQt时,老提示没有这个文件,需要自己找到源代码手工uic qaxselect.ui > ui_qaxselect.h来生成一下,Qt5中则解决了该问题。


9.使用到打印相关的类,Qt5单独放到了QtPrintSupport模块中,所以得加头文件#include <QtPrintSupport>,在.pro中要加QT += printsupport


10. 使用到QWebPage等webkit相关可视部件的,Qt5单独放到了QtWebKitWidgets模块中,所以得加头文件#include <QtWebKitWidgets>,在.pro中要加QT += webkitwidgets

11. Qt4中的cleanlooks、plastique、cde、motif等主题样式没有,新加了个fusion,好吧,问题是我的一个项目框架使用的是cleanlooks主题样式然后加自定义样式表,这下可好,升级Qt5后,样子有的就与windowsvista或fusion不相符或有缺陷,得调整一下了。所以,对主题样式依赖比较严重的程序,要衡量一下是否要升级到Qt5了。

12. .pro文件中的TARGET在Qt4(qmake v2)中是可以不填写的,那么它就从自动采用.pro文件名字,而在Qt5中(qmake v3)这个TARGET不可不写。

13. Q_WS_XXX已被废弃,使用Q_OS_XXX代替.

至于c++11 支持的连接信号与槽时可以不使用SLOT、SIGNAL宏的问题,现在先不改吧,虽然新方法去除了这两个宏,并且加强了类型检查,但也又增加了类名和一个&符号,先偷懒不动吧。

总的来说,将Qt4项目升级到Qt5,比较平滑,唯一比较累人的就是中文字符串问题了。






二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
离线dbzhang800

只看该作者 1楼 发表于: 2013-02-02
对于汉字编码问题,主要是MSVC和其他编译器行为不一致问题,比较简单的方法是:源文件都使用带BOM的UTF-8,然后添加

#if _MSC_VER >= 1600
#pragma execution_character_set("utf-8")
#endif

可解决 MSVC2010sp1+  的UTF-8问题
MSVC2008的话,需要打一个补丁 http://support.microsoft.com/kb/980263
离线XChinux

只看该作者 2楼 发表于: 2013-02-02
很久以前是一直用MinGW来着,用的UTF-8,为了和Linux GCC行为一致。后来使用ICE的时候,官方不提供MinGW版本的,就换MSVC了(当时还用MSVC2005),结果需要加BOM的UTF-8,为了MinGW、MSVC兼容,就改用GBK编码了。现在结果Qt又默认使用UTF-8,本来挺好的,就是MSVC问题不好处理,所以还得用GBK,并且历史及现维护项目都使用的是GBK,都换成UTF-8可能有未知问题(有调用WIN32 API的情况),所以还是用GBK吧。只不过以后写程序多加个宏或内联函数调用就行了。当然了,通用程序最好还是不写汉字而使用翻译。

发现许多开源库对MSVC不感冒,根本不提供MSVC的编译包或编译方式,这多麻烦。现在项目中用到了GMP C++接口,结果编译MSVC动态库好麻烦或根本就不支持(没见代码中有关于DLL类导出相关的东西,所以想使用C++接口只能调用静态库)。还有顶楼中所说的OWC10的问题,如果不升级的话,机器中永远得留着MSVC2008+Qt4.7.4,所以干脆全转成MinGW算了,逐渐升级到Qt5上面。其实MSVC挺不错的,它的发布基本上都是两年到三年一个大版本,然后后面跟个补丁版本。这样一个大版本,基本上能使用五年左右,甚至更长,保持了相对稳定,MinGW就麻烦点,GCC版本在不断的升级,自身build版本也众多,只能随手升级了。只要Qt官方能在每个发布包中提供MinGW就OK了,也省得自己安装MinGW和编译Qt了,上次编译了一次完整的4.8.4 release,花了三个小时,太麻烦了。很怀念4.3时代一次MSVC release编译只20分钟。以后遇到非MSVC不可的情况(比如这个ICE),就自己封装DLL供Qt/MinGW调用吧。
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
离线roywillow

只看该作者 3楼 发表于: 2013-02-02
回 1楼(dbzhang800) 的帖子
好像pro文件用带bom的utf8不能被qmake处理?

同样对于mingw如此众多的版本感觉很纠结……
专业维修核潜艇,回收二手航母、二手航天飞机,大修核反应堆,拆洗导弹发动机更换机油,无人侦察机手动挡改自动,航天飞机保养换三滤,飞碟外太空年检 ,各型号导弹加装迎宾踏板,高空作业擦洗卫星表面除尘、打蜡及抛光,东风全系列巡航导弹。并提供原子对撞机。量大从优,有正规发票。
离线dbzhang800

只看该作者 4楼 发表于: 2013-02-02
Re:回 1楼(dbzhang800) 的帖子
引用第3楼roywillow于2013-02-02 15:33发表的 回 1楼(dbzhang800) 的帖子 :
好像pro文件用带bom的utf8不能被qmake处理?

对,.pro/.pri/.prf/.prl 文件本身只支持 ASCII,不支持UTF8。

当时我考虑的是,直接跳过UTF-8开头的BOM(这样,所有的文件,包括qml,都可以使用带BOM的utf8),但是Oswald Buddenhagen不同意(因为qmake不能真正处理utf8字符,怕给用户造成误导),所以最终方案是:遇到BOM时,让qmake给出一个错误信息而后退出(最新的QtCreator应该也会强制删除pro文件的BOM)。
离线realfan

只看该作者 5楼 发表于: 2013-02-02
回 3楼(roywillow) 的帖子
Qt5.0.1又把mingw打包在里面了,以后就用这个版本的mingw了
离线XChinux

只看该作者 6楼 发表于: 2013-02-02
下午又将一个自己写的项目框架升级到了Qt5,遇到9到12号问题,加到了主题帖中。


二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
离线roywillow

只看该作者 7楼 发表于: 2013-02-02
回 6楼(XChinux) 的帖子
那几个样式好像还是可以作为插件提供的
专业维修核潜艇,回收二手航母、二手航天飞机,大修核反应堆,拆洗导弹发动机更换机油,无人侦察机手动挡改自动,航天飞机保养换三滤,飞碟外太空年检 ,各型号导弹加装迎宾踏板,高空作业擦洗卫星表面除尘、打蜡及抛光,东风全系列巡航导弹。并提供原子对撞机。量大从优,有正规发票。
离线XChinux

只看该作者 8楼 发表于: 2013-02-02
Re:回 6楼(XChinux) 的帖子
引用第7楼roywillow于2013-02-02 16:39发表的 回 6楼(XChinux) 的帖子 :
那几个样式好像还是可以作为插件提供的

是需要自己编译吧?源代码中没有找到。

二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
离线XChinux

只看该作者 9楼 发表于: 2013-02-02
似乎发现Qt5的那几个大DLL很不耐压,一压缩后没多大(Release版)。文件模块拆分的比较小,所以看似文件比较多,实际上增加的体积没有那么恐怖。

二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
离线roywillow

只看该作者 10楼 发表于: 2013-02-02
回 8楼(XChinux) 的帖子
我记得在changelog还是什么地方看到过,说如果需要可以自己单独编译插件,估计要自己去gitorious上下源码
专业维修核潜艇,回收二手航母、二手航天飞机,大修核反应堆,拆洗导弹发动机更换机油,无人侦察机手动挡改自动,航天飞机保养换三滤,飞碟外太空年检 ,各型号导弹加装迎宾踏板,高空作业擦洗卫星表面除尘、打蜡及抛光,东风全系列巡航导弹。并提供原子对撞机。量大从优,有正规发票。
离线dbzhang800

只看该作者 11楼 发表于: 2013-02-02
移除的类都在单独的仓库中,可以根据 自己的需要选择

qtstyleplugins
qtftp
qthttp
...

见:http://qt.gitorious.org/qt/
离线realfan

只看该作者 12楼 发表于: 2013-02-02
回 9楼(XChinux) 的帖子
我习惯用静态编译,然后用upx把exe压缩一下
离线dbzhang800

只看该作者 13楼 发表于: 2013-02-02
Re:回 9楼(XChinux) 的帖子
引用第12楼realfan于2013-02-02 19:04发表的 回 9楼(XChinux) 的帖子 :
我习惯用静态编译,然后用upx把exe压缩一下

多数人是使用LGPL授权的Qt来编写的闭源代码,不便(不能)采用静态发布的。
离线XChinux

只看该作者 14楼 发表于: 2013-02-02
引用第11楼dbzhang800于2013-02-02 17:03发表的  :
移除的类都在单独的仓库中,可以根据 自己的需要选择
qtstyleplugins
qtftp
qthttp
.......

编译cleanlooks时链接失败。还是用默认样式吧,我这程序客户对界面没啥要求。
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
在线uidab

只看该作者 15楼 发表于: 2013-02-04
回 12楼(realfan) 的帖子
我也尝试过压缩exe文件,可是在使用打包工具打包产品后发现并没有少多少!

另外,MSVC的升级周期长是挺好的,这样开发工具可以稳定工作若干个项目。 现在mingw和Qt的更新感觉有时候太快了!!
有时候为了工作直接获得答案,而我却失去了思考的乐趣!


飘啊飘,何时能安居!
离线realfan

只看该作者 16楼 发表于: 2013-02-04
回 15楼(uidab) 的帖子
静态生成的exe,用upx压缩,一般可以减少体积一半以上。

升级周期短,你们项目可以自己决定是否跟进呀。至少有的选择。
离线realfan

只看该作者 17楼 发表于: 2013-02-06
Re:Re:回 9楼(XChinux) 的帖子
引用第13楼dbzhang800于2013-02-02 19:12发表的 Re:回 9楼(XChinux) 的帖子 :
多数人是使用LGPL授权的Qt来编写的闭源代码,不便(不能)采用静态发布的。


这倒也是。Qt商业版一个License几千刀,个人是不会买的。
离线realfan

只看该作者 18楼 发表于: 2013-02-28
回 13楼(dbzhang800) 的帖子
动态编译,把生成的exe及dll,用Enigma Virtual Box打包成一个exe文件也可以。这样应该不违反LGPL吧。
不过Qt5的dll数量比qt4多好多,而且体积也大。
离线XChinux

只看该作者 19楼 发表于: 2013-02-28
昨天移植一个Qt4项目到Qt5,连接不上MSSQL,后来才发现是因为获取不到MSSQL Driver字符串(我从注册表中已注册的ODBC驱动来获取的),再后来才发现因为我将这段代码封在了#ifdef Q_WS_WIN里了,这段代码根本就没有执行,网上一查才知道原来Qt5中废弃了Q_WS_WIN、Q_WS_X11等这些宏,可使用Q_OS_XXX代替,所以将这条规则加到主帖中第13个问题中了。
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
离线XChinux

只看该作者 20楼 发表于: 2013-02-28
Re:回 13楼(dbzhang800) 的帖子
引用第18楼realfan于2013-02-28 09:10发表的 回 13楼(dbzhang800) 的帖子 :
动态编译,把生成的exe及dll,用Enigma Virtual Box打包成一个exe文件也可以。这样应该不违反LGPL吧。
不过Qt5的dll数量比qt4多好多,而且体积也大。


话说现在我也不管那么多了,反正我这边学项目都是针对企业客户的,对软件包大小不那么敏感,干脆一并将全部必要DLL全带过去,省得一个一个确认拷贝了。
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
离线alexltr

只看该作者 21楼 发表于: 2013-04-14
今天也把一个项目升级到了Qt5,有了上面的信息,过程基本上还算顺利。
我用到的东西不是很多,遇到的问题大致是上面提到的1,4,11点。
我也比较喜欢用cleanlooks样式,可惜Qt5没有了。

另外我还遇到了一个上面没有提到的问题:
在我的几个继承于QAbstractTableModel的类中用到了reset()函数,但在Qt5中好像不能用了,出现了莫名其妙的错误。
把这个函数换成了以下代码,不知道是不是这样,没有找到相关的说明。
  1. beginResetModel();
  2.      ..................
  3. endResetModel();



我不从事IT,只是喜欢Qt。
我不是程序员,只是与程序有缘。
我写程序,只是为了让工作变得简单有序!

                      ----  一个一直在入门的编程学习者
离线晤小晤

只看该作者 23楼 发表于: 2014-10-14
非常感谢!
快速回复
限100 字节
 
上一个 下一个