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

發佈了64 篇原創文章 · 獲贊 57 · 訪問量 25萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章