技術在不斷進步,新知識也理應不斷學習!Qt5的發布帶給我無盡的好奇心,然而,受項目影響,一直使用VS2008+Qt4.8.3也未曾及時更新。這幾天,果斷裝上VS2010+Qt5.1.0,開始研究。Qt4過渡到Qt5不算顯著,然而,“模塊化”的Qt代碼需要項目配置的變化,如使用“headers”,和配置項目構建(如改變*.pro文件)。
QtWidgets作為一個獨立的模塊
例如編譯時錯誤
-
error: QMainWindow: No such file or directory
-
error : QWidget: No such file or directory
解決辦法:
在*.pro文件里添加:
-
QT += widgets
更改
-
#include <QtGui>
為
-
#include <QtWidgets>
程序現在應該就可以運行了,但是有時可能需要更加明確的包含
-
#include <QtWidgets/QToolButton>
QtWebKitWidgets也是一個獨立的模塊:
例如編譯時錯誤
-
error: invalid use of incomplete type 'class QWebFrame'
-
error : forward declaration of 'class QWebFrame'
解決辦法:
在*.pro文件里添加:
-
QT += webkitwidgets
注意:當有QT += webkitwidgets的時候,就不再需要QT += widgets
此外,更改
-
#inclue <QtWebKit>
為
-
#include <QtWebKitWidgets>
打印機不工作
如果你的代碼有以下幾行:
-
#include <QPrinter>
-
#include <QPrintDialog>
將以下內容添加到項目文件中:
-
Qt += printsupport
同樣,有時可能仍無法正常工作,需要指定:
-
#include <QtPrintSupport/ QPrinter >
-
#include <QtPrintSupport/ QPrintDialog>
toAscii()和fromAscii()已被棄用
替換
-
fromAscii()
-
toAscii()
為
-
fromLatin1()
-
toLatin1()
例如,給定的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 ) ) ;
變為
QWorkspace已被棄用
這個類已經過時,在Qt4.3中被替換為QMdiArea。在Qt5中QWorkspace已被刪除。新的類與QWorkspace有類似的API,移植只涉及改變幾個方法、信號和槽的名字。
更換
-
#include <QWorkspace>
為
-
#include <QMdiAre>
QDrag問題
拖動功能的應用程序將需要一些調整。如:
-
QDrag *drag = new QDrag(event->widget());
在Qt5中將產生錯誤
-
error : no matching function for call to 'QDrag::QDrag(QWidget*)'
要解決這個附加組件,其中包括:
-
#include <QWidget>
qFindChildren已被棄用
這種方式會彈出一個錯誤:
-
error : 'qFindChildren' was not declared in this scope
為了解決這個問題,將qFindChildren替換為findChildren,例如
-
[... ]
-
-
if (m_children ) {
-
[... ]
替換
為
qVariantValue已被棄用
編譯器會出現
-
error : 'qVariantValue' was not declared in this scope
此功能相當於的QVariant::value(value)。因此,如果指定QVariant val應改寫
為
QTime用尖括號括起來,則告知編譯器QVariant將返回。但是,如果變量不是一個QVariable,則類型用尖括號括起來就不應該被使用(這樣做將導致一個模糊的編譯時錯誤)。所以指定的m_color(QColor類型),應改寫
為
-
s. setValue ( "color/favorite" , m_color. value ( ) ) ;
qVariantCanConvert已被棄用
替換
為
Qt::escape已被棄用
-
error : 'escape' is not a member of 'Qt'
所以應該更改下面代碼:
-
else
-
return result ;
為
-
else
-
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
CONFIG += qtestlib已被棄用
如果在項目文件中使用,則編譯器會發出警告,盡管如此代碼將照常運行:
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 <QtConcurrent/ QtConcurrent >
到項目文件,並添加下面一行:
-
LIBS += - lQt5Concurrent
固定的#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配置選項。
推薦閱讀
- C++ API Changes [qt-project.org]
- The porting guide [qt-project.org]
- Porting Desktop Applications from Qt 4 to Qt 5 [blog.ics.com]
- Porting from Qt 4 to Qt 5 [kdab.com]
- Automated porting from Qt 4 to Qt 5 [kdab.com]
- Converting a Qt 4 project to Qt 5 – General Advice and Difficulties [codeproject.com]
類別: