ПУСТО

пятница, 26 июня 2015 г.

Переход от Qt4 к Qt5

Это так, заметки для себя. Частичный перевод.
Модульность Qt требует некоторых изменений конфигурации проекта, при переносе его с Qt4 на Qt5. Это, использование иных подключаемых заголовочных файлов, и иная конфигурация проекта (изменения в * .pro файле).

QtWidgets в Qt5 это отдельный модуль

 

Пример ошибки компиляции

 

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

 

Решение


Добавить в ваш  *.pro файл:
1
QT += widgets
А так же заменить везде
1
#include <QtGui>
на
1
#include <QtWidgets>
Этого в принципе достаточно,  но иногда вам может потребоваться, чтобы подключение заголовочного файла было более явным:

1
#include <QtWidgets/QToolButton>

QtWebKitWidgets в Qt5 это так же отдельный модуль


Пример ошибки компиляции


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

Решение

 

Добавить в ваш  *.pro файл:
1
QT += webkitwidgets
А так же заменить везде
1
#include <QtWebKit>
на
1
#include <QtWebKitWidgets>

QPrinter в Qt5


Если ваш код имеет следующие строки:
1
2
#include <QPrinter>
#include <QPrintDialog>
добавьте следующую строку в ваш файл проекта:
1
QT + = printsupport
И опять же, подключение заголовочных фалов должно быть таким:
1
2
#include <QtPrintSupport/QPrinter>
#include <QtPrintSupport/QPrintDialog>

Методы ToAscii() и fromAscii() в Qt5 считаются устаревшими


Замените все экземпляры
fromAscii ()
ToAscii ()
на
fromLatin1 ()
toLatin1 ()

Например, если код Qt4 был следующим:
1
QByteArray configfileti = TMP_Config.toAscii();
То в Qt5 он должен быть изменен на:
1
QByteArray configfileti = TMP_Config.toLatin1();

QCoreApplication::UnicodeUTF8 в Qt5 устарела


Нужно совершить замену как в примере ниже.
Код в Qt4:
1
2
3
4
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));
В Qt5 должен быть заменен на:
1
2
3
4
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 в Qt5 устарела


Этот класс в Qt5 устарел и был заменен классом QMdiArea. Новый класс имеет аналогичный API как и у QWorkspace и при переносе приложений где он используется нужно будет изменить названия нескольких методов, сигналов и слотов. А так же заменить везде:
1
#include <QWorkspace>
На
1
#include <QMdiArea>

Проблемы в Qt5 с QDrag


Приложения Qt4 имеющие подобную строку
1
QDrag *drag = new QDrag(event->widget());

при компиляции в Qt5 будут выдавать ошибку
1
error: no matching function for call to 'QDrag::QDrag(QWidget*)'

Для исправления, подключите заголовочный файл:
1
#include <QWidget>

qFindChildren в Qt5 устарела


Появляется ошибка:
1
error: 'qFindChildren' was not declared in this scope
Чтобы решить эту проблему замените qFindChildren на findChildren, например, следующий код:
1
2
3
4
5
6
toString(const QObject* obj, int indentLevel) const {
[…]
 /* Query over QObjects */
 if (m_children) {
 QList<QObject*> childlist = qFindChildren<QObject*>(obj, QString());
[…]
должен быть изменен на код:
1
QList<QObject*> childlist = qFindChildren<QObject*>(obj, QString());

qVariantValue в Qt5 устарела


Появляется ошибка:
1
error: 'qVariantValue' was not declared in this scope
Например, код в Qt4:
1
QTime t = qVariantValue<qtime>(val);
В Qt5 меняем на:
1
QTime t = val.value<qtime>();
И так же, например, код в Qt4:
1
s.setValue("color/favorite", qVariantValue<qcolor>(m_color));
В Qt5 меняем на:
1
s.setValue("color/favorite", m_color.value());

qVariantCanConvert в Qt5 устарела


Замените
1
2
3
Q_ASSERT(qVariantCanConvert<qstring>(variant));
Q_ASSERT(qVariantCanConvert<qsize>(variant));
Q_ASSERT(qVariantCanConvert<qfont>(fontVariant));

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

Qt::escape в Qt5 устарела


Появляется ошибка:
1
error: 'escape' is not a member of 'Qt'
Например, код в Qt4:
1
2
3
4
5
if (result == QString())
    result = Qt::escape(val.toString());
else
    result = Qt::escape(result);
return result;
В Qt5 меняем на:
1
2
3
4
5
if (result == QString())
    result = QString(val.toString()).toHtmlEscaped();
else
    result = QString(result).toHtmlEscaped();
return result;

QDesktopServices::storageLocation в Qt5 устарела


Появляется ошибки:
1
2
error: 'storageLocation' is not a member of 'QDesktopServices'
error: 'DataLocation' is not a member of 'QDesktopServices'
Например, код в Qt4:
1
QString path = s.value("db.path", QDesktopServices::storageLocation(QDesktopServices::DataLocation)).toString();
В Qt5 меняем на:
1
QString path = s.value("db.path", QStandardPaths::standardLocations(QStandardPaths::DataLocation)).toString();

CONFIG+=qtestlib в Qt5 устарела


Если у вас есть в файле проектастрока CONFIG+=qtestlib компилятор предупредит вас в окне компиляции, но код будет работать как обычно
1
Project WARNING: CONFIG+=qtestlib is deprecated. Use QT+=testlib instead.

Причуды в Qt5 с QWeakPointer


Следующий код в Qt4
1
2
3
quint64 decodedPointer = line.toULongLong();
MetaData* md = reinterpret_cast<MetaData*>(decodedPointer);
QWeakPointer<metadata> wp(md);

В Qt5 вызывает появление ошибки
1
error: no matching function for call to 'QWeakPointer<metadata>::QWeakPointer(MetaData*&)'
Для исправления, добавте в файл проекта строку
1
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0

Если в Qt5 пропала библиотека QtConcurrent


Появляется ошибки:
1
2
C:\Qt\5.0.2\5.0.2\mingw47_32\include\QtConcurrent\qtconcurrentthreadengine.h:133: error: undefined reference to
`_imp___ZN12QtConcurrent16ThreadEngineBaseD2Ev'
В Qt4, QtConcurrent был частью QtCore, и не было необходимости подключать дополнительные заголовочные файлы. Но в Qt5 использование QtConcurrent иначе. Например, если есть код
1
m_current = QtConcurrent::blockingMappedReduced(slices, functor, stitchReduce, QtConcurrent::UnorderedReduce );

То нужно подключить заголовочный файл:
1
#include <QtConcurrent/QtConcurrent>

и добавить следующую строку в файл проекта:
1
QT+= concurrent

В Qt5 точность QTimer по умолчанию больше не до миллисекунд


В Qt5 QUrl addQueryItem переехал в QUrlQuery


В Qt5 QAbstractItemModel изменен


Qt5 - Развертывание на системах без C++11


Нужна перекомпиляция исходников.

Fixing #include<> Headers


Этот документ перевод этого.

Так же рекомендуемая литература:

C++ API Changes
The porting guide
Porting Desktop Applications from Qt 4 to Qt 5
Porting from Qt 4 to Qt 5
Automated porting from Qt 4 to Qt 5

Комментариев нет:

Отправить комментарий