Spec-Zone.ru › Qt 5.6

Система метаобъектов

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

Система метаобъектов основана на трех компонентах:

  1. Класс QObject служит базовым классом для объектов, которые могут использовать систему метаобъектов.
  2. Макрос Q_OBJECT внутри раздела private объявления класса используется для включения функций метаобъектов, таких как динамические свойства, сигналы и слоты.
  3. Компилятор метаобъектов Meta-Object Compiler (moc) предоставляет каждому подклассу QObject необходимый код для реализации функций метаобъектов.

Инструмент moc читает файл исходного кода C++. Если он обнаруживает одно или несколько объявлений классов, содержащих макрос Q_OBJECT, он генерирует другой файл исходного кода C++, который содержит код метаобъектов для каждого из этих классов. Этот сгенерированный файл исходного кода либо #include в файл исходного кода класса, либо, чаще, компилируется и подключается к реализации класса.

Помимо предоставления механизма сигналов и слотов для взаимодействия между объектами (основная причина введения системы), код метаобъектов предоставляет следующие дополнительные функции:

  • QObject::metaObject() возвращает связанный метаобъект метаобъект для класса.
  • QMetaObject::className() возвращает имя класса в виде строки во время выполнения без необходимости поддержки информации о типе во время выполнения (RTTI) через компилятор C++.
  • Функция QObject::inherits() возвращает значение, указывающее, является ли объект экземпляром класса, который наследуется от указанного класса в дереве наследования QObject.
  • QObject::tr() и QObject::trUtf8() переводят строки для локализаций.
  • QObject::setProperty() и QObject::property() динамически устанавливают и получают свойства по имени.
  • QMetaObject::newInstance() создает новый экземпляр класса.

Также возможно выполнять динамическое приведение типов, используя qobject_cast() для классов QObject. Функция qobject_cast() работает аналогично стандартному C++ dynamic_cast(), с преимуществами, что она не требует поддержки RTTI и работает через границы динамических библиотек. Она пытается привести свой аргумент к типу указателя, указанному в угловых скобках, возвращая ненулевой указатель, если объект имеет правильный тип (определяется во время выполнения), или 0, если тип объекта несовместим.

Например, предположим, что MyWidget наследуется от QWidget и объявлен с помощью макроса Q_OBJECT:

    QObject *obj = new MyWidget;

Переменная obj, типа QObject *, фактически ссылается на объект MyWidget, поэтому мы можем корректно привести её тип:

    QWidget *widget = qobject_cast<QWidget *>(obj);

Приведение типа от QObject к QWidget успешно, так как объект фактически является MyWidget, который является подклассом QWidget. Поскольку мы знаем, что obj является MyWidget, мы также можем привести его к типу MyWidget *:

    MyWidget *myWidget = qobject_cast<MyWidget *>(obj);

Приведение типа к MyWidget успешно, потому что qobject_cast() не делает различий между встроенными типами Qt и пользовательскими типами.

    QLabel *label = qobject_cast<QLabel *>(obj);
    // label is 0

Приведение типа к QLabel, с другой стороны, терпит неудачу. Указатель затем устанавливается в 0. Это позволяет обрабатывать объекты разных типов по-разному во время выполнения, в зависимости от типа:

    if (QLabel *label = qobject_cast<QLabel *>(obj)) {
        label->setText(tr("Ping"));
    } else if (QPushButton *button = qobject_cast<QPushButton *>(obj)) {
        button->setText(tr("Pong!"));
    }

Хотя возможно использовать QObject в качестве базового класса без макроса Q_OBJECT и без кода метаобъектов, ни сигналы и слоты, ни другие описанные здесь функции не будут доступны, если макрос Q_OBJECT не используется. С точки зрения системы метаобъектов, подкласс QObject без мета-кода эквивалентен своему ближайшему предку с кодом метаобъекта. Это означает, например, что QMetaObject::className() не вернёт фактическое имя вашего класса, а имя класса этого предка.

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

См. также QMetaObject, Система свойств Qt и Сигналы и слоты.

© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/archives/qt-5.11/metaobjects.html

Spec-Zone.ru

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