Как подключить QML к C++: объявляем свой первый контекст и объект

Автор: | 19 января, 2026

В первом материале мы создали минимальное Qt Quick-приложение и разобрались, как QML загружается из C++. Следующий логичный шаг — связать QML с C++-логикой: передать объект в QML, вызвать методы и получить данные.

В этой статье мы разберём:

  • что такое QML context
  • как передать C++-объект в QML
  • как вызывать C++-методы из интерфейса
  • какие ошибки совершают новички

Что такое QML Context

QML Context — это область видимости, в которой QML видит объекты и свойства из C++.

Проще говоря:

Context — это мост между C++ и QML.

Существует несколько способов экспорта C++ в QML:

  1. setContextProperty() — просто и быстро
  2. qmlRegisterType() — масштабируемо
  3. Singleton-объекты
  4. Модели (QAbstractItemModel)

В этой статье используем первый способ, как самый наглядный.


Создаём C++ backend-класс

Начнём с минимального объекта, который будет доступен из QML.

backend.h

#pragma once
#include <QObject>

class Backend : public QObject
{
    Q_OBJECT

public:
    explicit Backend(QObject *parent = nullptr);

    Q_INVOKABLE QString message() const;
};

backend.cpp

#include "backend.h"

Backend::Backend(QObject *parent)
    : QObject(parent)
{
}

QString Backend::message() const
{
    return "Сообщение из C++ backend";
}

Ключевые моменты

  • QObject — обязателен
  • Q_OBJECT — включает meta-object систему
  • Q_INVOKABLE — делает метод доступным из QML

Регистрируем объект в QML-контексте

Теперь передадим экземпляр Backend в QML.

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>

#include "backend.h"

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;

    Backend backend;
    engine.rootContext()->setContextProperty("backend", &backend);

    engine.load(QUrl(QStringLiteral("qrc:/qml/Main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}

Теперь объект backend доступен глобально во всём QML.


Используем C++-объект в QML

Main.qml

import QtQuick 2.15
import QtQuick.Controls 2.15

ApplicationWindow {
    visible: true
    width: 400
    height: 300
    title: "QML ↔ C++"

    Column {
        anchors.centerIn: parent
        spacing: 10

        Text {
            id: label
            text: "Ожидание..."
        }

        Button {
            text: "Вызвать C++"
            onClicked: label.text = backend.message()
        }
    }
}

При нажатии кнопки QML вызывает C++-метод напрямую.


Добавляем свойства (Q_PROPERTY)

Методы — это хорошо, но QML лучше работает с реактивными свойствами.

Обновим backend.h

class Backend : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString status READ status NOTIFY statusChanged)

public:
    explicit Backend(QObject *parent = nullptr);

    QString status() const;

    Q_INVOKABLE void updateStatus();

signals:
    void statusChanged();

private:
    QString m_status;
};

backend.cpp

Backend::Backend(QObject *parent)
    : QObject(parent),
      m_status("Стартовое состояние")
{
}

QString Backend::status() const
{
    return m_status;
}

void Backend::updateStatus()
{
    m_status = "Обновлено из C++";
    emit statusChanged();
}

Использование свойства в QML

Text {
    text: backend.status
}

Button {
    text: "Обновить"
    onClicked: backend.updateStatus()
}

Теперь QML автоматически обновляется при изменении данных в C++.

Возможные ошибки

Ошибка 1: забыли Q_OBJECT
→ QML не видит методы и свойства.

Ошибка 2: объект создан в стеке, но удалён раньше QML
→ приложение падает.

Ошибка 3: логика в QML вместо C++
→ сложность поддержки.

Ошибка 4: setContextProperty для больших проектов
→ лучше qmlRegisterType.

Итог

В этой статье мы:

  • разобрали, что такое QML context
  • передали C++-объект в QML
  • вызвали C++-методы из интерфейса
  • подключили реактивные свойства

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