Определение типов 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 "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.
По той же причине новые типы, введённые в более поздних версиях, должны использовать аргумент minor version функции 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 setExpired 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 MessageBoardAttachedType *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 *> 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.14/qtqml-cppintegration-definetypes.html