Spec-Zone.ru › Qt 5.15

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

Тип можно использовать в объявлении объекта из 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 "color" 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(расширенный) предназначен для регистрации расширенных типов. Аргументом является имя другого класса, используемого в качестве расширения.

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

При обработке этого кода движком 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 с квалификатором "MessageBoard". В терминах ранее описанных концепций, здесь задействованы следующие стороны:

  • Экземпляр анонимного типа присоединенного объекта, который предоставляет сигнал 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-5.15/qtqml-cppintegration-definetypes.html

Spec-Zone.ru

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