Введение в QML: декларативный UI в Qt

Автор: | 12 июня, 2025

QML (Qt Modeling Language) — это декларативный язык, предназначенный для описания пользовательского интерфейса (UI) в приложениях на Qt. Он создан для того, чтобы упростить разработку красивого, отзывчивого и анимированного интерфейса, особенно в сочетании с JavaScript и C++.

Что такое QML?

QML позволяет описывать интерфейс как дерево компонентов. Вы пишете интерфейс, как HTML или JSON, и Qt сам «рисует» его и связывает с логикой. Это особенно полезно для:

  • Мобильных и embedded-приложений
  • Графически насыщенных интерфейсов
  • Быстрой итерации дизайна

Пример простого QML-файла:

// main.qml
import QtQuick 2.15
import QtQuick.Controls 2.15

ApplicationWindow {
    visible: true
    width: 400
    height: 300
    title: "Пример QML"

    Button {
        text: "Нажми меня"
        anchors.centerIn: parent
        onClicked: {
            console.log("Кнопка нажата!")
        }
    }
}

Основные модули QML

  • QtQuick: базовые компоненты (прямоугольники, текст, анимации)
  • QtQuick.Controls: виджеты уровня UI (кнопки, поля ввода, меню)
  • QtQuick.Layouts: компоненты для компоновки (RowLayout, ColumnLayout)
  • QtGraphicalEffects: визуальные эффекты (тени, размытие и пр.)

Структура QML-файла

QML-файл представляет собой иерархию объектов:

Rectangle {
    width: 200
    height: 100
    color: "lightblue"

    Text {
        text: "Привет, QML!"
        anchors.centerIn: parent
    }
}

QML поддерживает:

  • Свойства (width, color, text)
  • Сигналы и обработчики (onClicked, onTextChanged)
  • Привязки значений (например, width: parent.width / 2)
  • Анимации
  • JavaScript-логику

Привязки и реактивность

QML построен на реактивной системе: если вы свяжете свойства, они будут автоматически обновляться:

Rectangle {
    width: 300
    height: 300

    Rectangle {
        width: parent.width / 2
        height: 50
        color: "green"
    }
}

Если parent.width изменится — внутренний Rectangle автоматически обновит свою ширину.

Связь с C++

Часто бизнес-логика и тяжелые вычисления реализуются в C++. Вы можете:

Регистрировать C++ классы в QML:

    qmlRegisterType<MyObject>("MyApp", 1, 0, "MyObject");

    Использовать QQmlContext для передачи объектов:

    QQmlApplicationEngine engine;
    engine.rootContext()->setContextProperty("myModel", &model);

    Вызвать слот из QML:

    Button {
        onClicked: myModel.doSomething()
    }
    

    Компоненты управления

    QML имеет собственные виджеты — проще и легче, чем Qt Widgets. Вот несколько:

    КомпонентНазначение
    ButtonКнопка
    TextFieldПоле ввода
    SliderПолзунок
    ListViewСписки
    DialogДиалоговое окно

    Анимации

    Одна из сильнейших сторон QML — это анимации:

    Rectangle {
        id: box
        width: 100; height: 100
        color: "red"
    
        MouseArea {
            anchors.fill: parent
            onClicked: box.width = 200
        }
    
        Behavior on width {
            NumberAnimation { duration: 300 }
        }
    }
    

    При клике ширина плавно изменится с 100 до 200 пикселей.

    Приложение на QML + C++

    Простой main.cpp:

    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    
    int main(int argc, char *argv[]) {
        QGuiApplication app(argc, argv);
        QQmlApplicationEngine engine;
        engine.load(QUrl("qrc:/main.qml"));
        return app.exec();
    }
    

    Преимущества QML

    • Декларативный и читаемый код UI
    • Быстрое прототипирование интерфейсов
    • Простые и мощные анимации
    • Реактивность (обновление UI без ручного контроля)
    • Отлично подходит для embedded и мобильной разработки

    Недостатки

    • Менее гибкий для сложных виджетов, чем Qt Widgets
    • Нужна интеграция с C++ для бизнес-логики
    • Поддержка IDE и дебаггера может быть неидеальной

    QML — это современный способ создавать интерфейсы в Qt, особенно когда важны графика, анимации и адаптивность. Его легко освоить, он отлично сочетается с C++, и позволяет быстро выводить продукт на экран.

    Раздел: QML Метки: