Spec-Zone.ru › Qt 5.9

Определение типов 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++, производный от 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, но может быть указан по имени типа.
  • 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 "color" Q_PROPERTY:

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

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)
    {
        qsrand(QDateTime::currentMSecsSinceEpoch() / 1000);
        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(qrand() % 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 *> 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.9/qtqml-cppintegration-definetypes.html

Spec-Zone.ru

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