Qt4過渡至Qt5


    技術在不斷進步,新知識也理應不斷學習!Qt5的發布帶給我無盡的好奇心,然而,受項目影響,一直使用VS2008+Qt4.8.3也未曾及時更新。這幾天,果斷裝上VS2010+Qt5.1.0,開始研究。Qt4過渡到Qt5不算顯著,然而,“模塊化”的Qt代碼需要項目配置的變化,如使用“headers”,和配置項目構建(如改變*.pro文件)。


QtWidgets作為一個獨立的模塊

例如編譯時錯誤

  1. error: QMainWindow: No such file or directory
  2. error :  QToolButton : No such file or directory
  3. error :  QWidget: No such file or directory

解決辦法:

在*.pro文件里添加:

  1. QT  +=  widgets

更改

  1. #include <QtGui>

  1. #include <QtWidgets>

程序現在應該就可以運行了,但是有時可能需要更加明確的包含

  1. #include <QtWidgets/QToolButton>

  

QtWebKitWidgets也是一個獨立的模塊:

例如編譯時錯誤

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

解決辦法:

在*.pro文件里添加:

  1. QT  +=  webkitwidgets

注意:當有QT += webkitwidgets的時候,就不再需要QT += widgets

此外,更改

  1. #inclue <QtWebKit>

  1. #include <QtWebKitWidgets>

  

打印機不工作

如果你的代碼有以下幾行:

  1. #include <QPrinter>
  2. #include <QPrintDialog>

將以下內容添加到項目文件中:

  1. Qt += printsupport

同樣,有時可能仍無法正常工作,需要指定:

  1. #include <QtPrintSupport/ QPrinter >
  2. #include  <QtPrintSupport/ QPrintDialog>

  

toAscii()和fromAscii()已被棄用

替換

  1. fromAscii()
  2. toAscii()

  1. fromLatin1()
  2. toLatin1()

例如,給定的Qt4代碼

  1. QByteArry configfileti  =  TMP_Config. toAscii() ;

變為

  1. QByteArry configfileti  =  TMP_Config. toLatin1() ;

  

QCoreApplication::UnicodeUTF8已被棄用

此枚舉類型用於定義8位編碼的字符串參數translate()。此枚舉現在已經過時,所有的情況將使用UTF-8所以刪除了QCoreApplication::UnicodeUTF8的所有實例。例如:

  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 ) ) ;

變為

  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已被棄用

這個類已經過時,在Qt4.3中被替換為QMdiArea。在Qt5中QWorkspace已被刪除。新的類與QWorkspace有類似的API,移植只涉及改變幾個方法、信號和槽的名字。

更換

  1. #include <QWorkspace>

  1. #include <QMdiAre>

  

QDrag問題

拖動功能的應用程序將需要一些調整。如:

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

在Qt5中將產生錯誤

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

要解決這個附加組件,其中包括:

  1. #include <QWidget>

 

qFindChildren已被棄用

這種方式會彈出一個錯誤:

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

為了解決這個問題,將qFindChildren替換為findChildren,例如

  1. toString ( const  QObject * obj ,  int indentLevel )  const  {
  2. [... ]
  3.     
  4.      if  (m_children )  {
  5.          QList <</span>QObject*> childlist = qFindChildren<</span>QObject*>(obj, QString());
  6. [... ]

替換

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

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


qVariantValue已被棄用

編譯器會出現

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

此功能相當於的QVariant::value(value)。因此,如果指定QVariant val應改寫

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

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

QTime用尖括號括起來,則告知編譯器QVariant將返回。但是,如果變量不是一個QVariable,則類型用尖括號括起來就不應該被使用(這樣做將導致一個模糊的編譯時錯誤)。所以指定的m_color(QColor類型),應改寫

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

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


qVariantCanConvert已被棄用

替換

  1. Q_ASSERT (qVariantCanConvert <</span>QString>(variant));
  2. Q_ASSERT (qVariantCanConvert <</span>QSize>(variant));
  3. Q_ASSERT (qVariantCanConvert <</span>QFont>(fontVariant));

  1. Q_ASSERT (variant. canConvert ( QMetaType :: QString ) ) ;
  2. Q_ASSERT (variant. canConvert ( QMetaType :: QSize ) ) ;
  3. Q_ASSERT (fontVariant. canConvert ( QMetaType :: QFont ) ) ;

  

Qt::escape已被棄用

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

所以應該更改下面代碼:

  1.      if  (result  ==  QString ( ) )
  2.         result  =  Qt :: escape (val. toString ( ) ) ;
  3.      else
  4.         result  =  Qt :: escape (result ) ;
  5.      return result ;

  1.      if  (result  ==  QString ( ) )
  2.         result  =  QString (val. toString ( ) ). toHtmlEscaped ( ) ;
  3.      else
  4.         result  =  QString (result ). toHtmlEscaped ( ) ;
  5.      return result ;

  

QDesktopServices::storageLocation已被棄用

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

使用QStandardPaths::StandardLocation,替換

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

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


QtMutimedia替換了Phonon

音頻、視頻已不再使用 phonon, 如果你還在研究phonon,那么你已經out了!好好研究一下 QMediaPlayer、QMediaMetaData ...吧!

CONFIG += qtestlib已被棄用

如果在項目文件中使用,則編譯器會發出警告,盡管如此代碼將照常運行:

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

  

QWeakPointer怪異

如下代碼

  1. quint64 decodedPointer  = line. toULongLong ( ) ;
  2. MetaData  *md  =  reinterpret_cast <</span>MetaData*>(decodedPointer);
  3. QWeakPointer <</span>MetaData> wp(md);

結果

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

為了解決這個問題,將下面代碼添加到項目文件:

  1. DEFINES  += QT_DISABLE_DEPRECATED_BEFORE = 0


QtConcurrent庫的失蹤了?

  1. 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的情況下。如果源代碼如下

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

則將需要包含頭:

  1. #include <QtConcurrent/ QtConcurrent >

到項目文件,並添加下面一行:

  1. 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配置選項。


推薦閱讀

類別:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM