技术在不断进步,新知识也理应不断学习!Qt5的发布带给我无尽的好奇心,然而,受项目影响,一直使用VS2008 + Qt4.8也未曾及时更新。这几天,果断装上VS2010 + Qt5.1,开始研究。Qt4过渡到Qt5不算显著,然而,“模块化”的Qt代码也需要改变项目配置,如使用“headers”,和配置项目构建(如:改变*.pro文件)。
QtWidgets作为一个独立的模块
例如编译时错误
-
error: QMainWindow: No such file or directory
-
error
: QToolButton
: No such file or directory
-
error
:
QWidget: No such file or directory
解决办法:
在*.pro文件里添加:
更改
为
程序现在应该就可以运行了,但是有时可能需要更加明确的包含
QtWebKitWidgets也是一个独立的模块:
例如编译时错误
-
error: invalid use of incomplete type 'class QWebFrame'
-
error
: forward declaration of
'class QWebFrame'
解决办法:
在*.pro文件里添加:
注意:当有QT += webkitwidgets的时候,就不再需要QT += widgets
此外,更改
为
打印机不工作
如果你的代码有以下几行:
将以下内容添加到项目文件中:
同样,有时可能仍无法正常工作,需要指定:
-
#include
QPrinter
>
-
#include
QPrintDialog>
toAscii()和fromAscii()已被弃用
替换
为
例如,给定的Qt4代码
-
QByteArry configfileti
=
TMP_Config.
toAscii()
;
变为
-
QByteArry configfileti
=
TMP_Config.
toLatin1()
;
QCoreApplication::UnicodeUTF8已被弃用
此枚举类型用于定义8位编码的字符串参数translate()。此枚举现在已经过时,所有的情况将使用UTF-8。所以删除了QCoreApplication::UnicodeUTF8的所有实例。例如:
-
Href_Gui
->
setWindowTitle
(
QApplication
::
translate
(
"Href_Gui"
,
"Url / www"
,
0
,
QApplication
::
UnicodeUTF8
)
)
;
-
label
->
setText
(
QApplication
::
translate
(
"Href_Gui"
,
"Text:"
,
0
,
QApplication
::
UnicodeUTF8
)
)
;
-
label_2
->
setText
(
QApplication
::
translate
(
"Href_Gui"
,
"Url:"
,
0
,
QApplication
::
UnicodeUTF8
)
)
;
-
label_3
->
setText
(
QApplication
::
translate
(
"Href_Gui"
,
"Target / Name:"
,
0
,
QApplication
::
UnicodeUTF8
)
)
;
变为
-
Href_Gui
->
setWindowTitle
(
QApplication
::
translate
(
"Href_Gui"
,
"Url / www"
,
0
)
)
;
-
label
->
setText
(
QApplication
::
translate
(
"Href_Gui"
,
"Text:"
,
0
)
)
;
-
label_2
->
setText
(
QApplication
::
translate
(
"Href_Gui"
,
"Url:"
,
0
)
)
;
-
label_3
->
setText
(
QApplication
::
translate
(
"Href_Gui"
,
"Target / Name:"
,
0
)
)
;
QWorkspace已被弃用
这个类已经过时,在Qt4.3中被替换为QMdiArea。在Qt5中QWorkspace已被删除。新的类与QWorkspace有类似的API,移植只涉及改变几个方法、信号和槽的名字。
更换
为
QDrag问题
拖动功能的应用程序将需要一些调整。如:
-
QDrag *drag = new QDrag(event->widget());
在Qt5中将产生错误
-
error
: no matching function for call to
'QDrag::QDrag(QWidget*)'
要解决这个附加组件,其中包括:
qFindChildren已被弃用
这种方式会弹出一个错误:
-
error
:
'qFindChildren' was not declared in
this scope
为了解决这个问题,将qFindChildren替换为findChildren,例如
-
toString
(
const
QObject
* obj
,
int indentLevel
)
const
{
-
[...
]
-
-
if
(m_children
)
{
-
QList
<</span>QObject*> childlist = qFindChildren<</span>QObject*>(obj, QString());
-
[...
]
替换
-
QList
<</span>QObject*> childlist = qFindChildren<</span>QObject*>(obj, QString());
为
-
QList
<</span>QObject*> childlist = obj->findChildren<</span>QObject*>(QString());
qVariantValue已被弃用
编译器会出现
-
error
:
'qVariantValue' was not declared in
this scope
此功能相当于的QVariant::value(value)。因此,如果指定QVariant val应改写
-
QTime t
= qVariantValue
<</span>QTime>(val);
为
-
QTime t
= val.
value
<</span>QTime>();
QTime用尖括号括起来,则告知编译器QVariant将返回。但是,如果变量不是一个QVariable,则类型用尖括号括起来就不应该被使用(这样做将导致一个模糊的编译时错误)。所以指定的m_color(QColor类型),应改写
-
s.
setValue
(
"color/favorite"
, qVariantValue
<</span>QColor>(m_color));
为
-
s.
setValue
(
"color/favorite"
, m_color.
value
(
)
)
;
qVariantCanConvert已被弃用
替换
-
Q_ASSERT
(qVariantCanConvert
<</span>QString>(variant));
-
Q_ASSERT
(qVariantCanConvert
<</span>QSize>(variant));
-
Q_ASSERT
(qVariantCanConvert
<</span>QFont>(fontVariant));
为
-
Q_ASSERT
(variant.
canConvert
(
QMetaType
::
QString
)
)
;
-
Q_ASSERT
(variant.
canConvert
(
QMetaType
::
QSize
)
)
;
-
Q_ASSERT
(fontVariant.
canConvert
(
QMetaType
::
QFont
)
)
;
Qt::escape已被弃用
-
error
:
'escape' is not a member of
'Qt'
所以应该更改下面代码:
-
if
(result
==
QString
(
)
)
-
result
=
Qt
::
escape
(val.
toString
(
)
)
;
-
else
-
result
=
Qt
::
escape
(result
)
;
-
return result
;
为
-
if
(result
==
QString
(
)
)
-
result
=
QString
(val.
toString
(
)
).
toHtmlEscaped
(
)
;
-
else
-
result
=
QString
(result
).
toHtmlEscaped
(
)
;
-
return result
;
QDesktopServices::storageLocation已被弃用
-
error
:
'storageLocation' is not a member of
'QDesktopServices'
-
error
:
'DataLocation' is not a member of
'QDesktopServices'
使用QStandardPaths::StandardLocation,替换
-
QString path
= s.
value
(
"db.path"
,
QDesktopServices
::
storageLocation
(
QDesktopServices
::
DataLocation
)
).
toString
(
)
;
为
-
QString path
= s.
value
(
"db.path"
,QStandardPaths
::
standardLocations
(QStandardPaths
::
DataLocation
)
).
toString
(
)
;
QtMutimedia替换了Phonon
音频、视频已不再使用
phonon,
如果你还在研究phonon,那么你已经out了!好好研究一下
QMediaPlayer、QMediaMetaData ...吧!
CONFIG += qtestlib已被弃用
如果在项目文件中使用,则编译器会发出警告,尽管如此代码将照常运行:
-
Project WARNING
: CONFIG
+=qtestlib is deprecated.
Use
QT
+=testlib instead.
QWeakPointer怪异
如下代码
-
quint64 decodedPointer
= line.
toULongLong
(
)
;
-
MetaData
*md
=
reinterpret_cast
<</span>MetaData*>(decodedPointer);
-
QWeakPointer
<</span>MetaData> wp(md);
结果
-
error
: no matching function
for call to
'QWeakPointer::QWeakPointer(MetaData*&)'
为了解决这个问题,将下面代码添加到项目文件:
-
DEFINES
+= QT_DISABLE_DEPRECATED_BEFORE
=
0
QtConcurrent库的失踪了?
-
C:\Qt\Qt5.0.2\5.0.2\mingw47_32\include\QtConcurrent\qtconcurrentthreadengine.h:133: error: undefined reference to `_imp___ZN12QtConcurrent16ThreadEngineBaseD2Ev'
在Qt4中,QtConcurrent是QtCore的一部分,所以,没有必要包括特定的头。这已不再是用Qt5的情况下。如果源代码如下
-
m_current
= QtConcurrent
::
blockingMappedReduced
(slices
, functor
, stitchReduce
,QtConcurrent
::
UnorderedReduce
)
;
则将需要包含头:
到项目文件,并添加下面一行:
固定的#include <>头
在qtbase/bin/中存在一个“fixqt4headers.pl”这样的Perl脚本。运行于Qt源代码运行,为Qt组件纠正#include <>指令还要考虑模块名称。
插件加载
Q_EXPORT_PLUGIN,Q_EXPORT_PLUGIN2宏已经过时,新的宏为Q_PLUGIN_METADATA。新系统的优点是,它允许Qt来查询元数据的插件没有实际dlopen'ing它。这极大地提高了插件系统的性能和可靠性。
新Q_PLUGIN_METADATA宏包含QObject的派生类中加载插件时返回的Q_OBJECT宏。它包含插件IID并指向一个包含插件元数据的json文件。json文件被编译成插件,并不需要安装。
例如如何改变插件可以通过查找补丁,改变GIF图像格式的插件,请查看:http://qt.gitorious.org/qt/qtbase/commit/963b4c1647299fd023ddbe7c4a25ac404e303c5d.
部署的系统没有使用C++11
当Qt的系统上安装了C++11,建立从源代码的Qt库/框架链接,系统的C++ 11库(libc++)。这意味着Qt库/框架没有部署到没有安装C++11(如out-of-the-box Mac OS X 10.6)的系统。为了能够部署到系统仅支持较旧的C++标准(libstdc++),构建Qt源代码没有C++11配置选项。