Spec-Zone.ru › Qt 5.12

Определение типов 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, вызовите qmlRegisterType() для регистрации класса как типа QML в определенном пространстве имен типов. Клиенты могут затем импортировать это пространство имен для использования типа.

Например, предположим, что существует 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)
public:
    // ...
};

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

qmlRegisterType<Message>("com.mycompany.messaging", 1, 0, "Message");

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

import com.mycompany.messaging 1.0

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

Регистрация несоздаваемых типов

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

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

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

  • qmlRegisterType() (без параметров) регистрирует тип C++, который не создается и не может ссылаться из QML. Это позволяет двигателю приводить унаследованные типы, которые создаются из QML.
  • qmlRegisterInterface() регистрирует существующий тип интерфейса Qt. Тип не создается из QML, и вы не можете объявлять QML-свойства с ним. Использование свойств C++ этого типа из QML будет выполнять ожидаемые преобразования интерфейса.
  • qmlRegisterUncreatableType() регистрирует именованный тип C++, который не создается, но должен быть идентифицирован как тип в системе типов QML. Это полезно, если перечисления или прикрепленные свойства типа должны быть доступны из QML, но сам тип не должен быть создаваемым.
  • qmlRegisterSingletonType() регистрирует тип одиночного экземпляра, который может быть импортирован из 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 "цвет":

import MyThemeModule 1.0 as Theme

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

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

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

Примечание: Значения перечислений для зарегистрированных типов в 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)

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

Для регистрации новой ревизии класса в определенную версию используется следующая функция:

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

Для регистрации CppType версии 1 для MyTypes 1.1:

qmlRegisterType<CppType,1>("MyTypes", 1, 1, "CppType")

root доступна только при импорте MyTypes версии 1.1.

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

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

Вы также можете зарегистрировать ревизию базового класса, от которого зависит ваш тип, с помощью функции qmlRegisterRevision():

template<typename T, int metaObjectRevision>
int qmlRegisterRevision(const char *uri, int versionMajor, int versionMinor)

template<typename T, int metaObjectRevision>
int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& reason)

template<typename T, typename E, int metaObjectRevision>
int qmlRegisterExtendedUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& reason)

Например, если BaseType изменена и теперь имеет ревизию 1, вы можете указать, что ваш тип использует новую ревизию:

qmlRegisterRevision<BaseType,1>("MyTypes", 1, 1);

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

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

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

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

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

QLineEdit {
    leftMargin: 20
}

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

Функция qmlRegisterExtendedType() предназначена для регистрации расширенных типов. Обратите внимание, что она имеет две формы.

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

template<typename T, typename ExtendedT>
int qmlRegisterExtendedType()

Эти функции следует использовать вместо обычных qmlRegisterType() вариантов. Аргументы идентичны соответствующим функциям регистрации без расширения, за исключением параметра ExtendedT, который представляет тип объекта расширения.

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

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

Определение типов и атрибутов QML

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

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

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

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 является объектом-приемником, к которому присоединён экземпляр типа присоединённого объекта.
  • Keys является присоединяющим типом, который предоставляет объекту-приемнику именованный квалификатор «Keys», с помощью которого он может получить доступ к атрибутам типа присоединённого объекта.

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

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

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

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

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

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

  • объявляется как присоединяемый тип путём вызова макроса QML_DECLARE_TYPEINFO() с флагом QML_HAS_ATTACHED_PROPERTIES

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

Например, возьмём тип 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)
public:
    // ...
};

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

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

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

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

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

class MessageBoard : public QObject
{
    Q_OBJECT
public:
    static MessageBoard *qmlAttachedProperties(QObject *object)
    {
        return new MessageBoardAttachedType(object);
    }
};
QML_DECLARE_TYPEINFO(MessageBoard, QML_HAS_ATTACHED_PROPERTIES)

Теперь тип 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 миллисекунд. Кроме того, можно предоставить максимальное значение для этого генератора случайных чисел. Этот класс может быть реализован следующим образом:

class RandomNumberGenerator : public QObject, public QQmlPropertyValueSource
{
    Q_OBJECT
    Q_INTERFACES(QQmlPropertyValueSource)
    Q_PROPERTY(int maxValue READ maxValue WRITE setMaxValue NOTIFY maxValueChanged);
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 как источник значения свойства. Ниже он используется для изменения ширины Rectangle каждые 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")
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)
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-5.12/qtqml-cppintegration-definetypes.html

Spec-Zone.ru

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