Introduction to Q_PROPERTY macro in Qt

In Qt, Q_PROPERTYmacros, allow properties to be added to the meta-object meta-object system when declaring a class, so that instances of that class can be queried and changed at runtime, and properties can have different data types, such as QString, int, etc. , and can have read/write, read-only or notification capabilities, moreover, metadata can be set for each property, such as range, min/max, display name, etc.;

The basic syntax of the Q_PROPERTY macro to declare a property:

Q_PROPERTY(type name READ getFunction [WRITE setFunction]
           [RESET resetFunction] [NOTIFY notifySignal]
           [DESIGNABLE bool] [SCRIPTABLE bool] [STORED bool]
           [USER bool] [CONSTANT] [FINAL] [REQUIRED])
  • type: The data type of the attribute;
  • name: the name of the attribute;
  • READ getFunction: The name of the getter function used to read the property value, a public member function that must be prefixed with get;
  • [WRITE setFunction]: The name of the setter function used to set the property value, must be a public member function prefixed with set, in writable mode, this parameter is required;
  • [RESET resetFunction]: the name of the public member function used to reset the property value;
  • [NOTIFY notifySignal]: The name of the signal emitted when the property value changes;
  • [DESIGNABLE bool] [SCRIPTABLE bool] [STORED bool] [USER bool] [CONSTANT] [FINAL] [REQUIRED]: Some extra options, which can be added selectively as needed;
Q_PROPERTYExample code used in Qt Creator :

1. Create a new widget application project;

2. Create a new class in the project, name it Person, inherit from QObjectthe class, open person.hthe file, and add the following code:

Here, we add two properties: nameand age, namethe property is a string, and agethe property is an integer, and for each property, we specify its readers and writers, and their corresponding signals;

#ifndef PERSON_H
#define PERSON_H

#include <QObject>

class Person : public QObject
{
    
    
    Q_OBJECT
    // 在此处声明属性
    Q_PROPERTY(QString name READ getName WRITE setName NOTIFY nameChanged)
    Q_PROPERTY(int age READ getAge WRITE setAge NOTIFY ageChanged)

public:
    explicit Person(QObject *parent = nullptr);
    ~Person() override;

    // 声明属性的读取器(getter)
    QString getName() const;
    int getAge() const;

    // 声明属性的写入器(setter)
    void setName(const QString &name);
    void setAge(int age);

signals:
    // 声明属性变化的信号
    void nameChanged(const QString &newName);
    void ageChanged(int newAge);

private:
    QString m_name;
    int m_age;
};

#endif // PERSON_H

3. In person.cppthe file, add the following code:

Here, we have implemented Personthe attribute methods in the class, and they are all very simple: getName()and getAge()return the values ​​of the member variables of m_nameand respectively, and set and according to the parameters , and emit corresponding signals;m_agesetName()setAge()m_namem_age

#include "person.h"

Person::Person(QObject *parent) : QObject(parent), m_age(0)
{
    
    

}

Person::~Person()
{
    
    

}

QString Person::getName() const
{
    
    
    return m_name;
}

int Person::getAge() const
{
    
    
    return m_age;
}

void Person::setName(const QString &name)
{
    
    
    if (m_name != name) {
    
    
        m_name = name;
        emit nameChanged(m_name);
    }
}

void Person::setAge(int age)
{
    
    
    if (m_age != age) {
    
    
        m_age = age;
        emit ageChanged(m_age);
    }
}

Person4. Now we can use this class in the main function , open widget.cppthe file, and add the following code:

Here, we create a new Personobject, use setProperty()the method to set the value of its nameand ageproperties, and query it, then we use setName()the and setAge()method to manually change the property value, and trigger the corresponding signal, finally, we will The object is deleted to release resources;

#include "widget.h"
#include "ui_widget.h"
#include "person.h"
#include <QDebug>


Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    
    
    ui->setupUi(this);

    // 创建一个新的 Person 对象
    auto person = new Person(this);

    // 设置属性的值
    person->setProperty("name", "Tom");
    person->setProperty("age", 21);

    // 查询属性的值并输出结果
    qDebug() << person->property("name").toString();
    qDebug() << person->property("age").toInt();

    // 更改属性的值并再次查询
    person->setProperty("name", "Jerry");
    person->setProperty("age", 22);

    qDebug() << person->property("name").toString();
    qDebug() << person->property("age").toInt();

    // 手动触发属性变化的信号
    person->setName("Rick");
    person->setAge(23);

    // 释放资源
    delete person;
}

Widget::~Widget()
{
    
    
    delete ui;
}


Guess you like

Origin blog.csdn.net/qq_33867131/article/details/130390233