Spec-Zone.ru › Qt 5.11

Определение типов 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":

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 миллисекунд. Кроме того, можно предоставить 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)
    {
        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 *> 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/archives/qt-5.11/qtqml-cppintegration-definetypes.html

Spec-Zone.ru

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