QtSeniorTechnical

Каковы основные различия между Qt 5 и Qt 6?

Qt 6 переработал систему типов (QList=QVector, qsizetype), перевёл Graphics View на RHI, убрал устаревшие API, добавил Qt Quick 3D и улучшил CMake-интеграцию. Миграция требует ручных правок и новой сборочной системы.

Основные различия между Qt 5 и Qt 6

Qt 6 вышел в декабре 2020 года и принёс значительные изменения в архитектуре, API и инфраструктуре сборки. Это не эволюционное обновление, а запланированный breaking release.

Система типов и контейнеры

  • QList в Qt 6 — это то, что раньше называлось QVector. Старый QList был основан на массиве указателей; теперь оба типа идентичны и хранят данные по значению в непрерывном блоке памяти.
  • Индексация контейнеров использует qsizetype (знаковый 64-битный на 64-битных платформах) вместо int — устраняет целочисленное переполнение для больших коллекций.
  • QStringView и QByteArrayView рекомендуются вместо передачи по const-ссылке для избежания копирования.
// Qt 5
QVector<int> vec = {1, 2, 3};
int size = vec.size(); // int

// Qt 6
QList<int> list = {1, 2, 3}; // QVector больше не нужен
qsizetype size = list.size(); // qsizetype

Система свойств (Qt Bindable Properties)

Qt 6 добавил QProperty<T> и QBindable<T> — реактивную систему связывания свойств без сигналов:

class Circle : public QObject {
    Q_OBJECT
    Q_PROPERTY(double radius READ radius WRITE setRadius BINDABLE bindableRadius)
public:
    QBindable<double> bindableRadius() { return &m_radius; }
    double radius() const { return m_radius; }
    void setRadius(double r) { m_radius = r; }
private:
    Q_OBJECT_BINDABLE_PROPERTY(Circle, double, m_radius);
};

Графический стек: RHI

Qt 6 заменил OpenGL как единственный бэкенд на RHI (Rendering Hardware Interface). Теперь рендеринг поддерживает Vulkan, Metal (macOS/iOS), Direct3D 12 и OpenGL. Старые шейдеры GLSL нужно портировать в SPIR-V через qsb:

# Компиляция шейдера для Qt 6 RHI
qsb --glsl "100 es,120,150" --hlsl 50 --msl 12 \
    -o shader.frag.qsb shader.frag

Система сборки: CMake вместо qmake

Qt 6 официально переключился на CMake. qmake ещё поддерживается, но новые возможности Qt 6 доступны только через CMake:

cmake_minimum_required(VERSION 3.16)
project(MyApp VERSION 1.0 LANGUAGES CXX)

find_package(Qt6 REQUIRED COMPONENTS Core Widgets Quick)
qt_standard_project_setup()

qt_add_executable(MyApp main.cpp)
qt_add_qml_module(MyApp
    URI MyApp
    VERSION 1.0
    QML_FILES Main.qml
)
target_link_libraries(MyApp PRIVATE Qt6::Core Qt6::Widgets Qt6::Quick)

Удалённые и изменённые API

  • QDesktopWidget удалён — используйте QScreen.
  • QLinkedList, QVector (как отдельный тип), QHash::insertMulti() удалены.
  • QString::null, QVariant::isNull() изменили поведение.
  • Сигнал QComboBox::activated(const QString&) удалён — только activated(int).
  • Qt::AA_DisableHighDpiScaling и AA_EnableHighDpiScaling удалены: High-DPI включён по умолчанию.

Новые возможности Qt 6

  • Qt Quick 3D: встроенный 3D-рендеринг через QML без Ogre/Babylon.
  • Qt Core permissions API: единый API для запроса разрешений на мобильных платформах.
  • Qt Concurrent переработан с поддержкой QtFuture::whenAll() и whenAny().
  • QSslServer: TLS-сервер без ручного подключения SSL к QTcpServer.

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

  • Замена QVector на QList меняет итераторную семантику в edge cases — проверьте код, работающий с указателями на элементы контейнера.
  • OpenGL-шейдеры из Qt 5 не компилируются напрямую; нужен инструмент qsb и пересборка ресурсов.
  • Старые .pro-файлы требуют полной переписки на CMake для доступа к новым модулям Qt 6.
  • Q_ENUM в Qt 6 строже: enum class не совместим с некоторыми вариантами QVariant::fromValue() без явной регистрации.
  • Qt WebEngine в Qt 6 требует Python 3 и Ninja в PATH во время сборки — на CI часто не установлены.
  • QML_ELEMENT и QML_SINGLETON (новый способ экспорта C++ в QML) несовместимы с qmake — только CMake.
  • Минимальная поддерживаемая версия компилятора для Qt 6: MSVC 2019, GCC 9, Clang 11 — устаревшие CI-образы нужно обновлять.
  • High-DPI по умолчанию ломает hardcoded размеры пикселей в Qt 5-коде — нужен аудит всех фиксированных размеров.

Common mistakes

  • Объяснять Qt 5 и Qt 6 различия только по синтаксису, без жизненного цикла и стоимости.
  • Игнорировать ошибки, null/empty состояния, порядок инициализации или режим сборки.
  • Давать пример, который работает в демо, но ломается при изменении владельца ресурса.
  • Смешивать signals/slots с generic callbacks и забывать про thread affinity.

What the interviewer is testing

  • Кандидат формулирует точную модель для Qt 5 и Qt 6 различия, а не только определение.
  • Пример компилируем, безопасен по lifetime и соответствует версии технологии.
  • Названы trade-off, ограничения и диагностируемые симптомы ошибки.
  • Понимает границу между C++ кодом, runtime/framework metadata и editor/UI слоем.

Sources

Related topics