Система свойств Qt
Qt предоставляет сложную систему свойств, аналогичную поставляемой некоторыми поставщиками компиляторов. Тем не менее, как библиотека, не зависящая от компилятора и платформы, Qt не полагается на нестандартные возможности компилятора, такие как __property или [property]. Наше решение работает с любым стандартным компилятором C++ на всех поддерживаемых нами платформах. Оно основано на мета-объектной системе, которая также предоставляет межобъектную связь посредством сигналов и слотов. ТребованияМакрос Q_PROPERTY() в объявлении класса объявляет свойство. Свойства могут быть объявлены только в классах, унаследованных от QObject. Для внешнего мира, свойство выглядит аналогично члену данных. Но свойства имеют несколько свойств, которые отличают их от обычных членов данных:
Функции чтения, записи и сброса могут быть почти функциями-членами, унаследованными или нет, виртуальными или нет. Единственным исключением является то, что функции-члены должны быть унаследованы от первого наследуемого класса в случае множественного наследования. Чтение и запись свойствСвойства можно читать и записывать посредством функций QObject не зная ничего об используемом классе. Во фрагменте кода ниже, вызов QObject::setProperty() эквивалентен вызову QAbstractButton::setDown(): QPushButton *button = new QPushButton;
QObject *object = button;
// кнопка и объект, указывает на тот же самый объект
button->setDown(true);
object->setProperty("down", true);
Эквивалентны, т.е., за исключением того, что первый вариант быстрее и предоставляет более лучшую диагностику во время компиляции. На практике первый - наилучший. Тем не менее, поскольку вы можете получить список всех доступных свойств для любого QObject посредством его QMetaObject, QObject::setProperty() может дать вам контроль над классами, которые не доступны во время компиляции. Так же как QObject::setProperty(), имеется соответствующая функция QObject::property(). QMetaObject::propertyCount() возвращает количество доступных свойств. QMetaObject::property() возвращает данные свойства для данного индекса свойства: объект QMetaProperty. Простой примерВот простой пример, который показывает использование наиболее важных функций свойства: class MyClass : public QObject { Q_OBJECT public: MyClass(QObject *parent = 0); ~MyClass(); enum Priority { High, Low, VeryHigh, VeryLow }; void setPriority(Priority priority); Priority priority() const; }; Класс имеет свойство priority, которое ещё не известно мета-объектной системе. Для того, чтобы сделать свойство известным, вы должны объявить его с помощью макроса Q_PROPERTY(). Синтаксис следующий: Q_PROPERTY(type name READ getFunction [WRITE setFunction] [RESET resetFunction] [DESIGNABLE bool] [SCRIPTABLE bool] [STORED bool]) Для корректного объявления, функция получения значения должна быть константной и возвращать либо сам тип, либо указатель или ссылку на него. Необязательная функция записи значения должна возвращать void и получать ровно один аргумент, либо сам тип, либо указатель или ссылку на него. Это навязывает мета-объектный компилятор. Тип свойства может быть любым поддерживаемым QVariant типом или типом перечисления, объявленным в самом классе. Так как MyClass использует для свойства Priority тип перечисления, этот тип должен быть также зарегистрирован с помощью системы свойств. Можно установить значение по имени, например так: obj->setProperty("priority", "VeryHigh"); В случае свойств QList и QMap, переданное значение является QVariant, чьим значением является весь список или отображение. Заголовочные файлыОбычно необходимо для включения заголовочных файлов для каждого типа значения, которое вы используете в определениях свойства. Например: Q_PROPERTY(QDate date READ getDate WRITE setDate) Так как свойство основано на классе QDate, заголовочный файл <QDate> будет включён в файл, содержащий вышеприведённое определение свойства. Использование перечислений и флагов в свойствахТипы перечислений регистрируются с помощью макроса Q_ENUMS(). Вот окончательное объявление класса, включающие объявления относящиеся к свойству: class MyClass : public QObject { Q_OBJECT Q_PROPERTY(Priority priority READ priority WRITE setPriority) Q_ENUMS(Priority) public: MyClass(QObject *parent = 0); ~MyClass(); enum Priority { High, Low, VeryHigh, VeryLow }; void setPriority(Priority priority); Priority priority() const; }; Обратите внимание на то, что если вы хотите зарегистрировать перечисление (используя Q_ENUMS()), которое объявлено в другом классе, перечисление должно быть полностью уточнённым с именем класса, объявившего его. Кроме того, класс объявивший перечисление унаследован от QObject, а также объявляет перечисление используя Q_ENUMS(). Другой аналогичный макрос - Q_FLAGS(). Аналогично Q_ENUMS(), он регистрирует тип перечисления, но отмечает в дополнение набор "флагов", т.е. значения перечисления могут соединены через ИЛИ. Класс ввода/вывода должен иметь значения перечисления Read и Write, а также принять Read | Write: например, перечисление лучше обрабатывается с помощью Q_FLAGS(), а не Q_ENUMS(). Типы свойствПомимо ключевых слов READ и WRITE, каждое объявление Q_PROPERTY() может содержать дополнительные ключевые слова, которые поставляют информацию о свойстве:
Добавление дополнительной информации в классПрикреплённые к системе свойств дополнительным макросом, Q_CLASSINFO(), который может использоваться для присоединения дополнительных пар имя--значение к мета-объекту класса, например: Q_CLASSINFO("Version", "3.0.0") Как и другие мета-данные, информация класса доступна во время выполнения через мета-объект; за подробностями обращайтесь к QMetaObject::classInfo(). Динамические свойстваВ дополнение к свойствам, определённым используя Q_PROPERTY в классе возможно динамическое добавление и удаление свойств любого QObject во время выполнения. Если вызывается setProperty со свойством не объявленном статически используя Q_PROPERTY, оно автоматически добавляется как динамическое свойство и его значение сохраняется в объекте. Значение может быть запрошено с использованием метода property(), также как со статическими свойствами. Смотрите также Мета-объектная система и Сигналы и слоты.
|
Попытка перевода Qt документации. Если есть желание присоединиться, или если есть замечания или пожелания, то заходите на форум: Перевод Qt документации на русский язык... Люди внесшие вклад в перевод: Команда переводчиков |