文档章节

The Transition from Qt 4.x to Qt 5

i
 imndszy
发布于 2016/05/22 13:02
字数 1442
阅读 10
收藏 0

oringinal website: http://qt-project.org/wiki/Transition_from_Qt_4.x_to_Qt5

 

The transition from Qt 4.x to Qt 5 is not expected to be significant. However, the “modularization” of the Qt code base requires some amount of changes to project configuration, such as use of “headers”, and configuration of project build settings (such as changes to the *.pro files).

Qt Creator (master) is compiled using Qt 4 and Qt 5; you can refer to its sources to get an overview of what is required to port an application and keep the sources backwards compatible to Qt 4.

QtWidgets as a Separate Module

example compile time errors

  1. error: QMainWindow: No such file or directory

  2. error: QToolButton: No such file or directory

  3. error: QWidget: No such file or directory

Solution

Add this in your *.pro file:

  1. QT += widgets

Change all instances of

  1. #include <QtGui>

to

  1. #include <QtWidgets>

The code should work now, though sometimes you may require to be more explicit:

  1. #include <QtWidgets/QToolButton>

QtWebKitWidgets is also a separate module:

example compile time errors

  1. error: invalid use of incomplete type 'class QWebFrame'

  2. error: forward declaration of 'class QWebFrame'

Solution

Add this in your *.pro file:

  1. QT += webkitwidgets

Note: when you have QT += webkitwidgets you don’t need QT += widgets

In addition, replace all instances of

  1. #include <QtWebKit>

to

  1. #include <QtWebKitWidgets>

You can try this by porting a WYSISWYG html editor [qt.gitorious.org] from Qt 4 to Qt 5.

QPrinter Doesn’t Work

If your code has the following lines:

  1. #include <QPrinter>

  2. #include <QPrintDialog>

add the following to your project file:

  1. QT += printsupport

Again, sometimes it may not work and you would need to be explicit:

  1. #include <QtPrintSupport/QPrinter>

  2. #include <QtPrintSupport/QPrintDialog>

toAscii() and fromAscii() Methods are deprecated

Replace all instances of

  1. fromAscii()

  2. toAscii()

to 

  1. fromLatin1()

  2. toLatin1()

For example, given the Qt 4 code

  1. QByteArray configfileti = TMP_Config.toAscii();

you would change to 

  1. QByteArray configfileti = TMP_Config.toLatin1();

QCoreApplication::UnicodeUTF8 is deprecated

This enum type used to define the 8-bit encoding of character string arguments to translate(). This enum is now obsolete and UTF-8 will be used in all cases. So remove all instances of QCoreApplication::UnicodeUTF8. For example:

  1. Href_Gui->setWindowTitle(QApplication::translate("Href_Gui", "Url / www", 0, QApplication::UnicodeUTF8));

  2. label->setText(QApplication::translate("Href_Gui", "Text:", 0, QApplication::UnicodeUTF8));

  3. label_2->setText(QApplication::translate("Href_Gui", "Url:", 0, QApplication::UnicodeUTF8));

  4. label_3->setText(QApplication::translate("Href_Gui", "Target / Name:", 0, QApplication::UnicodeUTF8));

to

  1. Href_Gui->setWindowTitle(QApplication::translate("Href_Gui", "Url / www", 0));

  2. label->setText(QApplication::translate("Href_Gui", "Text:", 0));

  3. label_2->setText(QApplication::translate("Href_Gui", "Url:", 0));

  4. label_3->setText(QApplication::translate("Href_Gui", "Target / Name:", 0));

QWorkspace is deprecated

This class is obsolete and was replaced by the QMdiArea class in Qt 4.3. In Qt 5 QWorkspace has been removed. The new class has a similar API to QWorkspace and porting it only involved changing the names of a few methods, signals, and slots.

replace

  1. #include <QWorkspace>

with

  1. #include <QMdiArea>

QDrag Problems

Apps that has drop and drag functionality will need some tweaking. A line such as

  1. QDrag *drag = new QDrag(event->widget());

in Qt 5 will generate the error

  1. error: no matching function for call to 'QDrag::QDrag(QWidget*)'

To fix this add among the includes:

  1. #include <QWidget>

qFindChildren is deprecated

An error will pop of this fashion:

  1. error: 'qFindChildren' was not declared in this scope

To solve this you replace qFindChildren with findChildren, for example in

  1. toString(const QObject* obj, int indentLevel) const {

  2. [...]

  3.     /* Query over QObjects */

  4.     if (m_children) {

  5.         QList<QObject*> childlist = qFindChildren<QObject*>(obj, QString());

  6. [...]

replace

  1. QList<QObject*> childlist = qFindChildren<QObject*>(obj, QString());

with

  1. QList<QObject*> childlist = obj->findChildren<QObject*>(QString());

source [bugs.webkit.org]

qVariantValue is deprecated

Your compiler will say

  1. error: 'qVariantValue' was not declared in this scope

This function is equivalent to QVariant::value<T>(value). Therefore if given a QVariant val rewrite the line

  1. QTime t = qVariantValue<QTime>(val);

to

  1. QTime t = val.value<QTime>();

This QTime enclosed in the angled brackets lets the compiler know what QVariant will return. However, if the variable is not a QVariable the type enclosed in the angled brackets should not be used(doing so will result in a vague compile time error). So given that m_color is of type QColor you will rewrite

  1. s.setValue("color/favorite", qVariantValue<QColor>(m_color));

to

  1. s.setValue("color/favorite", m_color.value());

source [stackoverflow.com]

qVariantCanConvert is deprecated

replace

  1. Q_ASSERT(qVariantCanConvert<QString>(variant));

  2. Q_ASSERT(qVariantCanConvert<QSize>(variant));

  3. Q_ASSERT(qVariantCanConvert<QFont>(fontVariant));

with

  1. Q_ASSERT(variant.canConvert(QMetaType::QString));

  2. Q_ASSERT(variant.canConvert(QMetaType::QSize));

  3. Q_ASSERT(fontVariant.canConvert(QMetaType::QFont));

Qt::escape is deprecated

  1. error: 'escape' is not a member of 'Qt'

So you would change the following block:

  1.     if (result == QString())

  2.         result = Qt::escape(val.toString());

  3.     else

  4.         result = Qt::escape(result);

  5.     return result;

to

  1.     if (result == QString())

  2.         result = QString(val.toString()).toHtmlEscaped();

  3.     else

  4.         result = QString(result).toHtmlEscaped();

  5.     return result;

this procedure can be automated by a porting tool [kdab.com] from KDAB.

QDesktopServices::storageLocation deprecated

  1. error: 'storageLocation' is not a member of 'QDesktopServices'

  2. error: 'DataLocation' is not a member of 'QDesktopServices'

Use QStandardPaths::StandardLocation:

  1. QString path = s.value("db.path",QDesktopServices::storageLocation(QDesktopServices::DataLocation)).toString();

to

  1. QString path = s.value("db.path",QStandardPaths::standardLocations(QStandardPaths::DataLocation)).toString();

source [qt-project.org]

CONFIG+=qtestlib is deprecated

If you have the above line in your project file the compiler will warn you in the compile window, nonetheless the code will still run as usual:

  1. Project WARNING: CONFIG+=qtestlib is deprecated. Use QT+=testlib instead.

QWeakPointer quirks

A code block like

  1. quint64 decodedPointer = line.toULongLong();

  2. MetaData* md = reinterpret_cast<MetaData*>(decodedPointer);

  3. QWeakPointer<MetaData> wp(md);

results in

  1. error: no matching function for call to 'QWeakPointer<MetaData>::QWeakPointer(MetaData*&)'

To fix this add to the project file:

  1. DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0

source [qt-project.org]

QtConcurrent Library is Missing?

  1. C:\Qt\Qt5.0.2\5.0.2\mingw47_32\include\QtConcurrent\qtconcurrentthreadengine.h:133: error: undefined reference to `_imp___ZN12QtConcurrent16ThreadEngineBaseD2Ev'

In Qt 4, QtConcurrent was part of QtCore, so there was no need to include specific headers. This is no longer the case with Qt 5. If your source code have lines like

  1. m_current = QtConcurrent::blockingMappedReduced(slices, functor, stitchReduce,QtConcurrent::UnorderedReduce );

You will need to include the header:

  1. #include <QtConcurrent/QtConcurrent>

and add the following line to your project file:

  1. LIBS += -lQt5Concurrent

Fixing #include<> Headers

A Perl script “fixqt4headers.pl” exists in qtbase/bin/. that should be run on source code using Qt that corrects the #include<> directives for Qt components to also consider the module name.

Plugin loading

The Q_EXPORT_PLUGIN,Q_EXPORT_PLUGIN2 macros have been deprecated in favor of the new Q_PLUGIN_METADATA macro. The advantage of the new system is that it allows Qt to query the metadata for the plugin without actually dlopen’ing it. This greatly improves performance and reliability of the plugin system.

The new Q_PLUGIN_METADATA macro is included next to the Q_OBJECT macro in the QObject derived class that is returned when loading the plugin. It contains the plugins IID and a filename pointing to a json file containing the metadata for the plugin. The json file is compiled into the plugin and does not need to be installed.

An example on how to change your plugins can be found by looking at the patch that changes the Gif image format plugin, see http://qt.gitorious.org/qt/qtbase/commit/963b4c1647299fd023ddbe7c4a25ac404e303c5d .

Deploying to systems without C++11

When Qt is built from source code on a system with C++11 installed, the Qt libraries/frameworks are linked against the system’s C++11 library (libc++). This means that the Qt libraries/frameworks are not deployable to systems without C++11 installed (such as out-of-the-box Mac OS X 10.6). To be able to deploy to systems that only support the older C++ standard (libstdc++), build Qt from source code with the -no-c++11 configure option.

QTimer is no longer accurate to the millisecond by default

QTimer has now 3 accuracy types, with a new default behaviour:

  • The new default type is Qt::CoarseTimer which, to reduce power/CPU consumption, allow 5% differencebetween requested time and actual one, and even allow the timer to fire before the requested time.
  • The former one is Qt::PreciseTimer (to the millisecond, never before the requested time).
  • A third one is Qt::VeryCoarseTimer and allow a 1 second difference

QUrl addQueryItem moved to QUrlQuery

If you have:

  1. QUrl url;

  2. // ...

  3. url.addQueryItem(key, value);

You will want to change it to

  1. QUrl url;

  2. QUrlQuery urlQuery;

  3. // ...

  4. urlQuery.addQueryItem(key, value);

  5.  

  6. url.setUrlQuery(urlQuery);

QAbstractItemModel changes

  1. void reset()

  2. void setRoleNames(const QHash<int, QByteArray> & roleNames)


both have changed and are now protected.

本文转载自:

i
粉丝 1
博文 19
码字总数 5128
作品 0
南京
私信 提问
Thoughts about Qt 5

Qt 4.0 was released in June 2005, almost six years ago. A lot has changed in the software industry over these years. While application development back then happened mostly on d......

IanSun
2011/05/15
0
0
MinGW下静态编译、链接Qt 5.0

本文讨论的将是MinGW之上的静态编译,并且将抛开万年难伺候的QtWebkit进行编译。 一、编译Qt 5.0 与Qt 4.x不同的地方: 1、Qt 5.0比以往相比,需要有perl环境。因此要在你的环境变量中添加p...

mickelfeng
2013/01/14
0
0
Nokia宣布Qt 5计划

Nokia Announces Qt 5 Plans Nokia宣布Qt 5计划 posted by Thom Holwerda on Mon 9th May 2011 21:14 UTC, submitted by Elv13 发表于:2011年5月10日 北京时间05:14 Since Nokia announced......

xyxzfj
2011/05/10
10
0
Qt 状态机框架学习

Qt状态机框架是基于状态图XML(SCXML) 实现的。从Qt4.6开始,它已经是QtCore模块的一部分。尽管它本身是蛮复杂的一套东西,但经过和Qt的事件系统(event system)、信号槽(signals and slots)及...

晨曦之光
2012/05/08
1K
0
QT 5.2 Beta 发布,移动开发者的福音

QT 5.2 Beta 发布了,该版本的 Qt Everywhere 已经足够稳定,提供 Android 和 iOS、Blackberry 10 上的 QT 移植版本;同时该版本引入新的 场景图形渲染器,该渲染器提升了图形的处理性能,对...

oschina
2013/10/24
8K
21

没有更多内容

加载失败,请刷新页面

加载更多

android6.0源码分析之Camera API2.0下的Preview(预览)流程分析

本文将基于android6.0的源码,对Camera API2.0下Camera的preview的流程进行分析。在文章android6.0源码分析之Camera API2.0下的初始化流程分析中,已经对Camera2内置应用的Open即初始化流程进...

天王盖地虎626
11分钟前
0
0
java 序列化和反序列化

1. 概述 序列恢复为Java对象的过程。 对象的序列化主要有两 首先我们介绍下序列化和反序列化的概念: 序列化:把Java对象转换为字节序列的过程。 反序列化:把字节序列恢复为Java对象的过程。...

edison_kwok
23分钟前
0
0
分布式数据一致性

狼王黄师傅
今天
1
0
经验

相信每位开发者在自己开发的过程中,都会反思一些问题,比如怎样提高编程能力、如何保持心态不砍产品经理、996 之后怎样恢复精力……最近开发者 Tomasz Łakomy 将他 7 年的开发生涯中学习到...

WinkJie
今天
4
0
从源码的角度来看SpringMVC

SpringMVC核心流程图 简单总结 首先请求进入DispatcherServlet 由DispatcherServlet 从HandlerMappings中提取对应的Handler 此时只是获取到了对应的Handle,然后得去寻找对应的适配器,即:H...

骚年锦时
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部