|
|||||||
Зачем нужен макрос Q_PROPERTY и как им пользоваться
Время создания: 13.02.2018 21:31
Текстовые метки: qt, Q_PROPERTY, QML
Раздел: Компьютер - Программирование - Язык C++ (Си++) - Библиотека Qt - Принципы написания кода
Запись: xintrea/mytetra_syncro/master/base/1518546701u9nvyxqgpb/text.html на raw.github.com
|
|||||||
|
|||||||
Макрос Q_PROPERTY необходим для того, чтобы программист имел возможность создавать класс со свойствами, поддерживаемыми метаобъектной подсистемой Qt. Для чего может понадобиться метаобъектная подсистема Qt? Например, если код пишется с использованием рефлексии, то у объекта можно узнавать перечень его свойств через QList<QByteArray> QObject::dynamicPropertyNames() const, или, например можно узнать имя класса в виде строки, вот так: // Имея указатель на объект, узнать имя класса как строку QObject *obj = new QPushButton; obj->metaObject()->className(); // returns "QPushButton" // Имея класс, узнать через специальный статический член имя класса как строку QPushButton::staticMetaObject.className(); // returns "QPushButton" Можно установить значение свойства по динамически изменяемому имени в виде строки, а не просто жестко прописывая в коде имя свойства. Делается это через метод: bool QObject::setProperty(const char *name, const QVariant &value) Точно так же, можно получать значение свойства по строке с именем свойства. Значение получается в виде QVariant: QVariant QObject::property(const char *name) const Кроме того, метаобъектная подсистема используется при программировании QML, для организации связки C++ и QML-кода. Связывать C++ и QML можно не только в режиме сигнал-слот, но и "пробрасывая" в QML объекты C++. Свойства класса, описанные в Q_PROPERTY, могут использоваться в QML-коде как обычные свойства QML-объектов. Кроме того, свойства Q_PROPERTY поддерживаются средой разработки QtCreator, и визуально отображаются в структуре класса (представление "Обзор классов"), а так же в интерфейсе QtDesigner. Что прописывается в макросе Q_PROPERTY? В макросе Q_PROPERTY много настроечных директив, но обычно Q_PROPERTY используют примерно так: class AppConfig : public QObject { Q_OBJECT Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled) ... Здесь имя свойства enabled - это именно то имя, под которым свойство будет видно в метаобъектной подсистеме для данного класса. Запись "bool enabled" не создает никакой C++ переменной для хранения значения свойства. Это просто объявление типа и имени свойства, которое будет доступно в метаобъектной подсистеме, и все. Для того, чтобы считывать значение свойства, программист должен прописать прототип и реализацию публичного метода isEnabled , который в данном случае должен выглядеть вот так: Файл заголовка (*.h - файл): class AppConfig : public QObject { Q_OBJECT Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled) public: bool isEnabled() ... Файл реализации (*.cpp - файл) bool AppConfig::isEnabled() { ... } Qt не накладывает никаких ограничений на то, что должно происходить внутри метода isEnabled(). Qt не интересует, откуда будет браться возвращаемое методом значение. Значение можно хранить в каком-нибудь свойстве класса, можно читать с файла или из базы данных, оно может быть корректным или некорректным - это не важно, реализация остается за программистом. Вызов isEnabled() производится в случае, если происходит считывание значения свойства enabled через метаобъектную систему. Так же, программист может просто вызывать данный метод чтобы получить значение этого свойства обычном способом в C++ коде. То же самое можно сказать и про метод setEnabled(). Его реализация может выглядеть так: void AppConfig::setEnabled(bool value) { ... } Опять же, совсем не важно, куда будет записываться переданное в сеттер значение. Реализация этого метода лежит на совести программиста. И все-таки, нужен пример реализации геттеров и сеттеров! Хорошо, вот пример. Значение сохраняется в отдельное свойство класса, именуемое e: Файл заголовка (*.h - файл): class AppConfig : public QObject { Q_OBJECT Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled) public: AppConfig(QObject *pobj=0); bool isEnabled(); void setEnabled(bool value); protected: bool e; }; Файл реализации (*.cpp - файл) AppConfig::AppConfig(QObject *pobj) { Q_UNUSED(pobj); } bool AppConfig::isEnabled() { return e; } void AppConfig::setEnabled(bool value) { e=value; } Свойство для хранения значения могло бы быть определено под любым именем, и даже как bool enabled; - это не принципиально. Например, если выделить мышкой макрос Q_PROPERTY, вызвать контекстное меню и выбрать "Рефакторинг" - "Создание отсутствующих членов Q_PROPERTY, то будет сгенерирован код, в котором свойство для хранения значения будет называться m_enabled. Вот, в принципе, и весь базис того, что необходимо знать о директиве Q_PROPERTY. |
|||||||
Так же в этом разделе:
|
|||||||
|
|||||||
|