Регистрация класса C++ для QML

Последнее обновление: 01.01.2024

Регистрация типов QML позволяет разработчику управлять жизненным циклом объекта C++ из среды QML. Этого невозможно достичь с помощью свойств контекста. В подобном случае объект C++ не является частью глобального контекста. Тем не менее, все типы необходимо сначала зарегистрировать.

Чтобы в коде QML использовать данные, функции или прочий функционал из кода C++, этот функционал должен быть оформлен в клас, скоторый является производным от QObject. Такое взаимодействие будет возможно, так как все типы объектов QML реализованы в виде классов, производных от QObject.

Итак, сначала добавим в проект новый класс C++. Если мы работаем в Qt Creator, то в структуре проекта нажмем на узел Source Files и в контекстном меню выберем Add New...

Добавление  класс C++ в Qt Creator

В окне добавления нового элемента выберем C++ Class

Добавление класса C++ в среде Qt Creator

На следующем шаге укажем для добавляемого класса какое-нибудь именя, например, в моем случае это "Custom"

Добавление и настройка класса C++ в среде Qt Creator

По умолчанию в проект будут добавлены два файла - файл с функционалом и заголовочный файл класса. В моем случае это "custom.cpp" и "custom.h".

Добавление файлов C++ в среде Qt Creator

В заголовочном файле custom.h пропишем следующий код:

#ifndef CUSTOM_H
#define CUSTOM_H

#include <QObject>

class Custom : public QObject
{
    Q_OBJECT
public:
    explicit Custom(QObject *parent = nullptr);
    Q_INVOKABLE int getTextSize() {return textSize; }
    Q_INVOKABLE QString getTextContent() {return textContent; }
private:
    int textSize {18};
    QString textContent {"Hello World"};
};

#endif // CUSTOM_H

Прежде всего нам надо унаследовать класс от QObject

class Custom : public QObject
{
    Q_OBJECT

Внутри класса с помощью встроенного макроса Q_OBJECT вставляем в класс весь необходимый функционал родительского класса.

Определяем конструктор, который в качестве может принимать через параметр типа QObject родительский контейнер

explicit Custom(QObject *parent = nullptr);

Чтобы сделать доступными для QML методы класса определяются с флагом Q_INVOKABLE. В данном случае у нас два таких метода, который просто возвращают значения приватных полей:

    Q_INVOKABLE int getTextSize() {return textSize; }
    Q_INVOKABLE QString getTextContent() {return textContent; }
private:
    int textSize {18};
    QString textContent {"Hello World"};

Метод getTextSize() возвращает целочисленное значение, а getTextContent() - строку в виде встроенного типа QString.

Далее в файле custom.cpp пропишем реализацию пустого конструктора

#include "custom.h"

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

Теперь для использования в QML этот тип надо зарегистрировать в главном файле программы main.cpp:

#include <QGuiApplication>
#include <QQmlApplicationEngine>

#include "custom.h" // подключаем определение нашего типа

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

    // регистрация типа
    qmlRegisterType<Custom>("custom", 1, 0,"Custom");

    const QUrl url("qrc:/path/main.qml");
    engine.load(url);

    return app.exec();
}

Здесь с помощью функции qmlRegisterType() регистрируется наш компонент Custom. Эта функция имеет следующее определение:

template<typename T>
int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName);

Эта функция-шаблон принимает следующие параметры:

  • uri - строка-идентификатор ресурса, по которой его можно подключить в QML

  • versionMajor - старшая версия компонента

  • versionMinor - младшая версия компонента

  • qmlName - строка с именем компонента, по которому он будет использоваться в QML

В данном случае класс Custom будет доступен в QML по имени "Custom", а для подключения будет применяться адрес "custom".

Теперь применим этот компонент в main.qml:

import QtQuick
import custom   // подключаем компонент Custom

Window {
    width: 250
    height: 200
    visible: true
    title: "METANIT.COM"

    Custom{             // Определяем объект Custom
        id:customObj    // назначаем его идентификатор
    }

    Text {
        anchors.centerIn: parent
        text: customObj.getTextContent()         // обращаемся к методам
        font.pixelSize: customObj.getTextSize()  // объекта Custom
        font.family: "Verdana"
    }
}

Поскольку для компонента Custom установлен uri "custom", то по этому uri подключаем его в файл qml. Далее мы можем создавать объекты Custom. В данном случае создается один объект, у которого просто устанавливается идентификатор customObj. После этого по данному идентифкатору мы можем обращаться к функциональности объекта. В частности, обращаемся к его методам для установки свойств объекта Text. Результат работы приложения:

Использование класса C++ в коде QML в Qt
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850