Различные статьи по Qt и c++

Миграция проекта с Qt5 на Qt6: чек-лист и частые проблемы

Переход с Qt5 на Qt6 — это не просто смена номера версии в файле сборки. Qt6 принёс изменения в систему сборки (переход на CMake как основной инструмент), переработку модулей (QtQuick, Qt Multimedia, Qt Positioning), отказ от ряда устаревших классов и переход на C++17 как минимальный стандарт. Для крупных проектов миграция может занять от нескольких дней до нескольких недель, поэтому важно подойти к ней системно.

Зачем мигрировать

Qt5 уже не получает новых функций, а коммерческая поддержка старых версий ограничена по времени. Qt6 даёт более быстрый рендеринг QML (новый RHI — Rendering Hardware Interface), улучшенную поддержку Unicode (QString теперь хранит UTF-8 внутри), а также активную разработку модулей вроде Qt Quick 3D и Qt Multimedia.

Чек-лист миграции

  1. Обновите систему сборки. Если проект использует qmake — рассмотрите переход на CMake, так как именно CMake является приоритетной системой сборки в Qt6.
  2. Проверьте минимальный стандарт C++. Qt6 требует C++17.
  3. Замените устаревшие API (см. отдельную статью с таблицей соответствий).
  4. Проверьте используемые модули. Некоторые модули были переименованы или объединены (например, Qt Quick Controls 1 удалён полностью).
  5. Пересоберите все плагины и сторонние библиотеки под Qt6 — бинарная совместимость с Qt5 отсутствует.
  6. Проверьте сериализацию данных, если используется QDataStream — формат версии потока изменился.
  7. Прогоните автотесты на каждом этапе миграции.

Пример: обновление CMakeLists.txt

cmake_minimum_required(VERSION 3.16)
project(MyApp LANGUACHES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)

# Поддержка одновременно Qt5 и Qt6 на время миграции
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Widgets)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Widgets)

add_executable(MyApp main.cpp mainwindow.cpp)

target_link_libraries(MyApp PRIVATE
    Qt${QT_VERSION_MAJOR}::Core
    Qt${QT_VERSION_MAJOR}::Widgets
)

if (QT_VERSION_MAJOR EQUAL 6)
    qt_finalize_executable(MyApp)
endif()

Такой приём с find_package(QT NAMES Qt6 Qt5 ...) позволяет одним CMakeLists.txt собирать проект и под Qt5, и под Qt6 на переходный период, что облегчает постепенную миграцию.

Типичные проблемы при компиляции

Проблема 1. QStringRef удалён.

// Qt5
QStringRef ref = str.midRef(2, 5);

// Qt6 — используем QStringView
QStringView ref = QStringView(str).mid(2, 5);

Проблема 2. Неявные преобразования QString → bool/int удалены.

В Qt6 ужесточена работа с неявными преобразованиями. Код вида if (myQString) больше не компилируется — нужно явно писать if (!myQString.isEmpty()).

Проблема 3. Изменение поведения QRegExp.

Класс QRegExp помечен устаревшим уже в Qt5, но в Qt6 он перенесён в отдельный модуль Qt5Compat. Рекомендуется переход на QRegularExpression:

// Было
QRegExp rx("\\d+");
if (rx.indexIn(text) != -1) { ... }

// Стало
QRegularExpression rx("\\d+");
QRegularExpressionMatch match = rx.match(text);
if (match.hasMatch()) { ... }

Проблема 4. QML import-версии.

В QML-файлах теперь не обязательно указывать минорную версию модуля:

// Qt5
import QtQuick 2.15
import QtQuick.Controls 2.15

// Qt6 — минорную версию можно не указывать
import QtQuick
import QtQuick.Controls

Подводные камни

  • Qt5Compat. Многие устаревшие классы (QTextCodec, QRegExp) доступны через дополнительный модуль Qt5Compat, который нужно подключать явно: find_package(Qt6 REQUIRED COMPONENTS Core5Compat).
  • Изменение порядка инициализации QML-движка может привести к тому, что синглтоны, зарегистрированные через qmlRegisterSingletonType, инициализируются позже, чем в Qt5.
  • Изменения в системе плагинов. Плагины (image format, sqldrivers) должны быть пересобраны заново — старые .dll/.so от Qt5 не подходят.
  • Различия в обработке High DPI. В Qt6 масштабирование High DPI включено по умолчанию и не настраивается через Qt::AA_EnableHighDpiScaling (атрибут удалён, так как поведение стало стандартным).

Совет: мигрируйте поэтапно

Не пытайтесь переписать весь проект за один присест. Разделите миграцию на этапы: сначала система сборки, затем устранение предупреждений компилятора, затем замена устаревших API, и только потом — полный переход на новые возможности Qt6 (например, Qt Quick 3D вместо самописного OpenGL-рендеринга). На каждом этапе прогоняйте полный набор тестов, чтобы локализовать регрессии.

================================================================================