Spec-Zone.ru › Qt 6.0

Определение типов QML из C++

При расширении QML кодом C++, класс C++ может быть зарегистрирован в системе типов QML, что позволит использовать этот класс в качестве типа данных в коде QML. Хотя свойства, методы и сигналы любого класса, производного от QObject, доступны из QML, как обсуждается в Предоставление атрибутов типов C++ в QML, такой класс не может быть использован как тип данных из QML, пока он не будет зарегистрирован в системе типов. Кроме того, регистрация может предоставить другие возможности, например, разрешить использовать класс как экземпляризуемый тип QML-объекта из QML или разрешить импортировать и использовать одиночный экземпляр класса из QML.

Кроме того, модуль Qt QML предоставляет механизмы для реализации QML-специфических функций, таких как прикреплённые свойства и свойства по умолчанию в C++.

(Обратите внимание, что ряд важных концепций, рассматриваемых в этом документе, продемонстрированы в учебнике по написанию расширений QML с помощью C++.)

Регистрация типов C++ в системе типов QML

Класс, производный от QObject, может быть зарегистрирован в системе типов QML, чтобы тип мог быть использован в качестве типа данных в коде QML.

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

Регистрация неэкземпляризуемого типа также регистрирует класс как тип данных таким образом, но тип не может быть использован для создания экземпляров как типа QML-объекта из QML. Это полезно, например, если тип имеет перечисления, которые должны быть доступны QML, но сам тип не должен быть экземпляризуем.

Для быстрого руководства по выбору правильного подхода к предоставлению типов C++ в QML, см. Выбор правильного метода интеграции между C++ и QML.

Регистрация экземпляризуемого типа объекта

Любой класс C++, производный от QObject, может быть зарегистрирован в качестве определения типа QML-объекта. После регистрации класса в системе типов QML класс можно объявлять и экземпляризовать, как любой другой тип объекта из кода QML. После создания экземпляр класса можно обрабатывать из QML; как объясняется в Предоставление атрибутов типов C++ в QML, свойства, методы и сигналы любого класса, производного от QObject, доступны из кода QML.

Чтобы зарегистрировать класс, производный от QObject, как экземпляризуемый тип QML-объекта, добавьте QML_ELEMENT или QML_NAMED_ELEMENT(<name>) в объявление класса и CONFIG += qmltypes, QML_IMPORT_NAME, и QML_IMPORT_MAJOR_VERSION в файл проекта. Это зарегистрирует класс в пространстве имен типов по заданной основной версии, используя либо имя класса, либо явно заданное имя в качестве имени типа QML. Незначительные версии будут выводиться из любых ревизий, прикреплённых к свойствам, методам или сигналам. По умолчанию незначительная версия равна 0. Вы можете явно ограничить доступ к типу только из определённых незначительных версий, добавив макрос QML_ADDED_IN_MINOR_VERSION() в объявление класса. Клиенты могут импортировать подходящие версии пространства имён, чтобы использовать тип.

Например, предположим, что существует класс Message с свойствами author и creationDate.

class Message : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString author READ author WRITE setAuthor NOTIFY authorChanged)
    Q_PROPERTY(QDateTime creationDate READ creationDate WRITE setCreationDate NOTIFY creationDateChanged)
    QML_ELEMENT
public:
    // ...
};

Этот тип может быть зарегистрирован путём добавления соответствующего пространства имен типа и номера версии в файл проекта. Например, чтобы сделать тип доступным в пространстве имён com.mycompany.messaging с версией 1.0:

CONFIG += qmltypes
QML_IMPORT_NAME = com.mycompany.messaging
QML_IMPORT_MAJOR_VERSION = 1

Если заголовок, в котором объявлен класс, недоступен из пути включения вашего проекта, вам может потребоваться изменить путь включения, чтобы сгенерированный код регистрации мог быть скомпилирован:

INCLUDEPATH += com/mycompany/messaging

Тип может быть использован в объявлении объекта из QML, и к его свойствам можно читать и записывать, как показано в примере ниже:

import com.mycompany.messaging 1.0

Message {
    author: "Amelie"
    creationDate: new Date()
}

Регистрация неэкземпляризуемых типов

Иногда может потребоваться зарегистрировать класс, производный от QObject, в системе типов QML, но не как экземпляризуемый тип. Например, это так, если класс C++:

  • является типом интерфейса, который не должен быть экземпляризуем
  • является типом базового класса, который не нужно предоставлять QML
  • объявляет перечисления, которые должны быть доступны QML, но при этом не должны быть экземпляризуемы
  • является типом, который должен быть предоставлен QML через одиночный экземпляр и не должен быть экземпляризуем из QML

Модуль Qt QML предоставляет несколько макросов для регистрации неэкземпляризуемых типов:

  • QML_ANONYMOUS регистрирует тип C++, который не может быть экземпляризован и не может быть вызван из QML. Это позволяет двигателю приводить любой наследуемый тип, который может быть экземпляризован из QML.
  • QML_INTERFACE регистрирует существующий тип интерфейса Qt. Тип не может быть экземпляризован из QML, и вы не можете объявлять свойства QML с ним. Использование свойств C++ этого типа из QML выполнит ожидаемые преобразования интерфейса.
  • QML_UNCREATABLE(reason) в сочетании с QML_ELEMENT или QML_NAMED_ELEMENT регистрирует именованный тип C++, который не может быть экземпляризован, но должен быть идентифицируемым типом для системы типов QML. Это полезно, если перечисления или присоединённые свойства типа должны быть доступны QML, но сам тип не должен быть экземпляризуем. Параметр должен быть сообщением об ошибке, которое будет выведено, если будет обнаружена попытка создать экземпляр типа.
  • QML_SINGLETON в сочетании с QML_ELEMENT или QML_NAMED_ELEMENT регистрирует тип одиночного экземпляра, который может быть импортирован из QML, как обсуждается ниже.

Обратите внимание, что все типы C++, зарегистрированные в системе типов QML, должны быть производными от QObject, даже если они не экземпляризуемы.

Регистрация одиночных объектов с типом одиночного экземпляра

Тип одиночного экземпляра позволяет предоставлять свойства, сигналы и методы в пространстве имён без необходимости для клиента вручную создавать экземпляр объекта. В частности, типы одиночных экземпляров QObject являются эффективным и удобным способом предоставления функциональности или глобальных значений свойств.

Обратите внимание, что типы одиночного экземпляра не имеют связанного QQmlContext, поскольку они совместно используются во всех контекстах в движке. Экземпляры типов одиночных экземпляров QObject создаются и владеют QQmlEngine, и они будут уничтожены при уничтожении движка.

С типом одиночного экземпляра QObject можно взаимодействовать аналогично любому другому типу QObject или экземпляризуемому типу, за исключением того, что существует только один (созданный и владеящий движком) экземпляр, и к нему необходимо обращаться по имени типа, а не по идентификатору. Свойства Q_PROPERTY типов одиночных экземпляров QObject могут быть связаны, и функции Q_INVOKABLE API модуля QObject могут быть использованы в выражениях обработчиков сигналов. Это делает типы одиночных экземпляров идеальным способом реализации стилей или тем, и их также можно использовать вместо импорта скриптов ".pragma library" для хранения глобального состояния или предоставления глобальной функциональности.

После регистрации тип одиночного экземпляра QObject может быть импортирован и использован как любой другой экземпляр QObject, доступный QML. Следующий пример предполагает, что тип одиночного экземпляра QObject был зарегистрирован в пространстве имён «MyThemeModule» с версией 1.0, где QObject имеет свойство QColor «цвет» Q_PROPERTY:

import MyThemeModule 1.0 as Theme

Rectangle {
    color: Theme.color // binding.
}

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

См. QML_SINGLETON для получения дополнительной информации о реализации и регистрации нового типа одиночного экземпляра и о том, как использовать существующий тип одиночного экземпляра.

Примечание: Значения перечислений для зарегистрированных типов в QML должны начинаться с заглавной буквы.

Ревизии и версии типов

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

Рассмотрим два файла QML:

// main.qml
import QtQuick 1.0

Item {
    id: root
    MyType {}
}
// MyType.qml
import MyTypes 1.0

CppType {
    value: root.x
}

где CppType сопоставляется с классом C++ CppType.

Если автор CppType добавит свойство root к CppType в новой версии определения своего типа, root.x теперь имеет другое значение, потому что root также является id верхнего уровня компонента. Автор может указать, что новое свойство root доступно с определённой незначительной версии. Это позволяет добавлять новые свойства и функции к существующим типам без нарушения работы существующих программ.

Тег REVISION используется для обозначения свойства root как добавленного в ревизии 1 типа. Методы, такие как Q_INVOKABLE, сигналы и слоты также могут быть помечены для ревизии с помощью макроса Q_REVISION(x).

class CppType : public BaseType
{
    Q_OBJECT
    Q_PROPERTY(int root READ root WRITE setRoot NOTIFY rootChanged REVISION 1)
    QML_ELEMENT

signals:
    Q_REVISION(1) void rootChanged();
};

Таким образом указанные ревизии автоматически интерпретируются как незначительные версии основной версии, указанной в файле проекта. В этом случае, root доступен только при импорте MyTypes версии 1.1 или выше. Импорт MyTypes версии 1.0 остаётся без изменений.

По той же причине новые типы, введенные в более поздних версиях, должны быть помечены макросом QML_ADDED_IN_MINOR_VERSION.

Эта функция языка позволяет вносить изменения в поведение без нарушения работоспособности существующих приложений. Поэтому авторы модулей QML всегда должны документировать, что изменилось между незначительными версиями, а пользователи модулей QML должны убедиться, что их приложение по-прежнему работает правильно перед развертыванием обновлённого оператора импорта.

Ревизии базового класса, от которого зависит ваш тип, автоматически регистрируются при регистрации самого типа. Это полезно при наследовании от базовых классов, предоставленных другими авторами, например, при расширении классов из модуля Qt Quick.

Примечание: Движок QML не поддерживает ревизии для свойств или сигналов групповых и присоединенных объектов свойств.

Регистрация объектов расширения

При интеграции существующих классов и технологий в QML API часто необходимо внести коррективы, чтобы лучше интегрироваться в декларативную среду. Хотя лучшие результаты обычно достигаются путем прямого изменения исходных классов, если это невозможно или затруднено по каким-либо причинам, объекты расширения позволяют ограниченные возможности расширения без непосредственных изменений.

Объекты расширения добавляют дополнительные свойства к существующему типу. Объекты расширения могут добавлять только свойства, а не сигналы или методы. Определение расширенного типа позволяет программисту предоставить дополнительный тип, известный как тип расширения, при регистрации класса. Свойства прозрачно объединяются с исходным целевым классом при использовании изнутри QML. Например:

QLineEdit {
    leftMargin: 20
}

Свойство leftMargin — это новое свойство, добавленное к существующему типу C++, QLineEdit, без изменения исходного кода.

Макрос QML_EXTENDED(расширенный) предназначен для регистрации расширенных типов. Аргументом является имя другого класса, используемого в качестве расширения.

Вы также можете использовать QML_EXTENDED_NAMESPACE(пространство имен) для регистрации пространства имен, а особенно перечислений, объявленных в нем, как расширение типа.

Класс расширения — это обычный QObject с конструктором, принимающим указатель на QObject. Однако создание класса расширения откладывается до первого доступа к расширенному свойству. Класс расширения создается, и целевой объект передается в качестве родителя. При доступе к свойству в оригинале вместо него используется соответствующее свойство объекта расширения.

Пример объектов расширения демонстрирует использование объектов расширения.

Определение типов и атрибутов, специфичных для QML

Предоставление присоединенных свойств

В синтаксисе языка QML существует понятие присоединенных свойств и присоединенных обработчиков сигналов, которые представляют собой дополнительные атрибуты, присоединенные к объекту. По существу, такие атрибуты реализуются и предоставляются типом присоединения, и эти атрибуты могут быть присоединены к объекту другого типа. Это контрастирует с обычными свойствами объектов, которые предоставляются самим типом объекта (или унаследованным типом объекта).

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

import QtQuick 2.0

Item {
    width: 100; height: 100

    focus: true
    Keys.enabled: false
    Keys.onReturnPressed: console.log("Return key was pressed")
}

Здесь объект Item может получать доступ к значениям и устанавливать значения Keys.enabled и Keys.onReturnPressed. Это позволяет объекту Item получить доступ к этим дополнительным атрибутам как расширению его собственных существующих атрибутов.

Шаги реализации присоединенных объектов

Рассматривая приведенный выше пример, участвуют несколько сторон:

  • Существует экземпляр анонимного типа присоединенного объекта с enabled и сигналом returnPressed, который был присоединен к объекту Item для обеспечения доступа и установки этих атрибутов.
  • Объект Item — это присоединяемый объект, к которому был присоединен экземпляр типа присоединенного объекта.
  • Ключи — это тип присоединения, который предоставляет присоединяемому объекту именованный квалификатор «Ключи», с помощью которого он может получить доступ к атрибутам типа присоединенного объекта.

При обработке этого кода движком QML он создает один экземпляр типа присоединенного объекта и присоединяет его к объекту Item, предоставляя ему доступ к атрибутам enabled и returnPressed экземпляра.

Механизмы предоставления присоединенных объектов могут быть реализованы с помощью C++, предоставляя классы для типа присоединенного объекта и типа присоединения. Для типа присоединенного объекта предоставьте класс, производный от QObject, который определяет атрибуты, которые должны быть доступны объектам присоединяемых объектов. Для типа присоединения предоставьте класс, производный от QObject, который:

  • реализует статический qmlAttachedProperties() со следующим сигнатурой:
    static <AttachedPropertiesType> *qmlAttachedProperties(QObject *object);

    Этот метод должен возвращать экземпляр типа присоединенного объекта.

    Движок QML вызывает этот метод, чтобы прикрепить экземпляр типа присоединенного объекта к присоединяемому объекту, указанному параметром object. Принято, хотя и не строго обязательно, чтобы эта реализация метода родила возвращенный экземпляр object, чтобы предотвратить утечки памяти.

    Этот метод вызывается движком не более одного раза для каждого экземпляра объекта присоединяемого объекта, так как движок кэширует возвращенный указатель экземпляра для последующего доступа к присоединенному свойству. Следовательно, объект присоединения может не удаляться до тех пор, пока объект присоединяемый object не будет уничтожен.

  • объявляется как тип присоединения, добавив макрос QML_ATTACHED(присоединенный) к объявлению класса. Аргументом является имя типа присоединенного объекта

Реализация присоединенных объектов: пример

Например, рассмотрим тип Message, описанный в предыдущем примере:

class Message : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString author READ author WRITE setAuthor NOTIFY authorChanged)
    Q_PROPERTY(QDateTime creationDate READ creationDate WRITE setCreationDate NOTIFY creationDateChanged)
    QML_ELEMENT
public:
    // ...
};

Предположим, необходимо сгенерировать сигнал на Message при публикации его на доске сообщений, а также отслеживать, когда сообщение истекло на доске сообщений. Поскольку добавление этих атрибутов непосредственно к Message не имеет смысла, так как атрибуты более релевантны контексту доски сообщений, их можно реализовать как присоединенные атрибуты к объекту Message с помощью квалификатора «Доска сообщений». В терминах ранее описанных понятий участвующие стороны здесь:

  • Экземпляр анонимного типа присоединенного объекта, который предоставляет сигнал published и свойство expired. Этот тип реализован в MessageBoardAttachedType ниже
  • Объект Message — это присоединяемый объект
  • Тип MessageBoard — это тип присоединения, который используется объектами Message для доступа к присоединенным атрибутам

Ниже приведен пример реализации. Сначала должен быть тип присоединенного объекта с необходимыми свойствами и сигналами, которые будут доступны присоединяемому объекту:

class MessageBoardAttachedType : public QObject
{
    Q_OBJECT
    Q_PROPERTY(bool expired READ expired WRITE setExpired NOTIFY expiredChanged)
    QML_ANONYMOUS
public:
    MessageBoardAttachedType(QObject *parent);
    bool expired() const;
    void setExpired(bool expired);
signals:
    void published();
    void expiredChanged();
};

Затем тип присоединения, MessageBoard, должен объявить метод qmlAttachedProperties(), который возвращает экземпляр типа присоединенного объекта, реализованного в MessageBoardAttachedType. Кроме того, MessageBoard должен быть объявлен как тип присоединения с помощью макроса QML_ATTACHED():

class MessageBoard : public QObject
{
    Q_OBJECT
    QML_ATTACHED(MessageBoardAttachedType)
    QML_ELEMENT
public:
    static MessageBoardAttachedType *qmlAttachedProperties(QObject *object)
    {
        return new MessageBoardAttachedType(object);
    }
};

Теперь тип Message может получить доступ к свойствам и сигналам типа присоединенного объекта:

Message {
    author: "Amelie"
    creationDate: new Date()

    MessageBoard.expired: creationDate < new Date("January 01, 2015 10:45:00")
    MessageBoard.onPublished: console.log("Message by", author, "has been
published!")
}

Кроме того, реализация на C++ может получить доступ к экземпляру присоединенного объекта, который был присоединен к любому объекту, вызвав функцию qmlAttachedPropertiesObject().

Например:

Message *msg = someMessageInstance();
MessageBoardAttachedType *attached =
        qobject_cast<MessageBoardAttachedType*>(qmlAttachedPropertiesObject<MessageBoard>(msg));

qDebug() << "Value of MessageBoard.expired:" << attached->expired();

Типы модификаторов свойств

Тип модификатора свойства — это особый вид типа QML-объекта. Экземпляр типа модификатора свойства влияет на свойство (экземпляра QML-объекта), к которому он применяется. Существует два разных вида типов модификаторов свойства:

  • интерцепторы записи значения свойства
  • источники значения свойства

Интерцептор записи значения свойства может использоваться для фильтрации или изменения значений при их записи в свойства. В настоящее время единственным поддерживаемым интерцептором записи значения свойства является тип Behavior, предоставляемый импортом QtQuick.

Источник значения свойства может использоваться для автоматического обновления значения свойства со временем. Клиенты могут определять свои собственные типы источников значения свойства. Различные типы анимации свойств, предоставляемые импортом QtQuick являются примерами источников значения свойства.

Экземпляры типа модификатора свойства могут быть созданы и применены к свойству QML-объекта с помощью синтаксиса «<ТипМодификатора> на <ИмяСвойства>», как показано в следующем примере:

import QtQuick 2.0

Item {
    width: 400
    height: 50

    Rectangle {
        width: 50
        height: 50
        color: "red"

        NumberAnimation on x {
            from: 0
            to: 350
            loops: Animation.Infinite
            duration: 2000
        }
    }
}

Клиенты могут регистрировать свои собственные типы источников значения свойства, но в настоящее время не интерцепторы записи значения свойства.

Источники значения свойства

Источники значения свойства — это типы QML, которые могут автоматически обновлять значение свойства со временем, используя синтаксис <PropertyValueSource> on <property>. Например, различные типы анимации свойств, предоставляемые модулем QtQuick являются примерами источников значения свойства.

Источник значения свойства можно реализовать на C++ путем наследования от QQmlPropertyValueSource и предоставления реализации, которая записывает различные значения в свойство со временем. Когда источник значения свойства применяется к свойству с помощью синтаксиса <PropertyValueSource> on <property> в QML, движок предоставляет ему ссылку на это свойство, чтобы значение свойства могло быть обновлено.

Например, предположим, что класс RandomNumberGenerator должен быть доступен как источник значения свойства, чтобы при применении к свойству QML он обновлял значение свойства на другое случайное число каждые 500 миллисекунд. Кроме того, может быть предоставлен maxValue для этого генератора случайных чисел. Этот класс можно реализовать следующим образом:

class RandomNumberGenerator : public QObject, public QQmlPropertyValueSource
{
    Q_OBJECT
    Q_INTERFACES(QQmlPropertyValueSource)
    Q_PROPERTY(int maxValue READ maxValue WRITE setMaxValue NOTIFY maxValueChanged);
    QML_ELEMENT
public:
    RandomNumberGenerator(QObject *parent)
        : QObject(parent), m_maxValue(100)
    {
        QObject::connect(&m_timer, SIGNAL(timeout()), SLOT(updateProperty()));
        m_timer.start(500);
    }

    int maxValue() const;
    void setMaxValue(int maxValue);

    virtual void setTarget(const QQmlProperty &prop) { m_targetProperty = prop; }

signals:
    void maxValueChanged();

private slots:
    void updateProperty() {
        m_targetProperty.write(QRandomGenerator::global()->bounded(m_maxValue));
    }

private:
    QQmlProperty m_targetProperty;
    QTimer m_timer;
    int m_maxValue;
};

Когда движок QML сталкивается с использованием RandomNumberGenerator в качестве источника значения свойства, он вызывает RandomNumberGenerator::setTarget() для предоставления типу свойства, к которому был применен источник значения.

Когда внутренний таймер в RandomNumberGenerator срабатывает каждые 500 миллисекунд, он записывает новое числовое значение в указанное свойство.

После регистрации класса RandomNumberGenerator в системе типов QML его можно использовать в QML в качестве источника значения свойства. Ниже он используется для изменения ширины Прямоугольника каждые 500 миллисекунд:

import QtQuick 2.0

Item {
    width: 300; height: 300

    Rectangle {
        RandomNumberGenerator on width { maxValue: 300 }

        height: 100
        color: "red"
    }
}

Во всех других отношениях, источники значений свойств являются обычными типами QML, которые могут иметь свойства, сигналы, методы и так далее, но с добавлением возможности изменения значений свойств с помощью синтаксиса <PropertyValueSource> on <property>.

Когда объект-источник значения свойства присваивается свойству, QML сначала пытается присвоить его обычным способом, как будто это обычный тип QML. Только если это присваивание завершается неудачей, движок вызывает метод setTarget(). Это позволяет использовать тип также в контекстах, отличных от просто источника значений.

Определение свойств по умолчанию для типов объектов QML

Любой тип, производный от QObject, зарегистрированный как экземплярируемый тип объекта QML, может по желанию указать свойство по умолчанию для типа. Свойство по умолчанию — это свойство, к которому автоматически присваиваются дочерние элементы объекта, если они не присвоены какому-либо конкретному свойству.

Свойство по умолчанию можно установить, вызвав макрос Q_CLASSINFO() для класса со значением "DefaultProperty". Например, класс MessageBoard ниже указывает своё свойство messages в качестве свойства по умолчанию для класса:

class MessageBoard : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QQmlListProperty<Message> messages READ messages)
    Q_CLASSINFO("DefaultProperty", "messages")
    QML_ELEMENT
public:
    QQmlListProperty<Message> messages();

private:
    QList<Message *> m_messages;
};

Это позволяет дочерним элементам объекта MessageBoard автоматически присваиваться его свойству messages, если они не присвоены конкретному свойству. Например:

MessageBoard {
    Message { author: "Naomi" }
    Message { author: "Clancy" }
}

Если messages не было установлено как свойство по умолчанию, то все объекты Message должны быть явно присвоены свойству messages, как показано ниже:

MessageBoard {
    messages: [
        Message { author: "Naomi" },
        Message { author: "Clancy" }
    ]
}

(Кстати, свойство Item::data является его свойством по умолчанию. Все объекты Item, добавленные в это свойство data, также добавляются в список Item::children, поэтому использование свойства по умолчанию позволяет объявлять визуальные дочерние элементы для элемента без явного присвоения их свойству children.)

Определение визуальных элементов с помощью модуля Qt Quick

При создании пользовательских интерфейсов с модулем Qt Quick все объекты QML, которые должны быть визуально отображены, должны быть производными от типа Item, так как это базовый тип для всех визуальных объектов в Qt Quick. Этот тип Item реализуется классом C++ QQuickItem, который предоставляется модулем Qt Quick. Поэтому этот класс следует наследовать, когда необходимо реализовать визуальный тип на C++, который можно интегрировать в пользовательский интерфейс на основе QML.

Дополнительную информацию см. в документации QQuickItem. Кроме того, учебник Создание расширений QML с помощью C++ демонстрирует, как реализовать визуальный элемент на основе QQuickItem на C++ и интегрировать его в пользовательский интерфейс на базе Qt Quick.

Получение уведомлений об инициализации объекта

Для некоторых пользовательских типов объектов QML может быть полезно отложить инициализацию определенных данных до создания объекта и установки всех его свойств. Например, это может быть необходимо, если инициализация является дорогостоящей или если инициализация не должна выполняться до тех пор, пока не будут инициализированы все значения свойств.

Модуль Qt QML предоставляет класс QQmlParserStatus для наследования в этих целях. Он определяет ряд виртуальных методов, которые вызываются на различных этапах создания компонента. Для получения этих уведомлений класс C++ должен унаследовать QQmlParserStatus и также уведомить систему метаданных Qt с помощью макроса Q_INTERFACES().

Например:

class MyQmlType : public QObject, public QQmlParserStatus
{
    Q_OBJECT
    Q_INTERFACES(QQmlParserStatus)
    QML_ELEMENT
public:
    virtual void componentComplete()
    {
        // Perform some initialization here now that the object is fully created
    }
};

© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-6.0/qtqml-cppintegration-definetypes.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API