在Qt中,Q_PROPERTY
宏,允许在声明类时将属性添加到 meta-object元对象 系统中,以便该类的实例可以在运行时被查询和更改,属性可以具有不同的数据类型,例如QString,int等,并且可以具有读/写,只读或通知功能,此外,可以为每个属性设置元数据,例如范围,最小/最大值,显示名称等;
Q_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
:属性的数据类型;name
:属性的名称;READ getFunction
:用于读取属性值的 getter 函数的名称,必须以 get 为前缀的公共成员函数;[WRITE setFunction]
:用于设置属性值的 setter 函数的名称,必须以 set 为前缀的公共成员函数,在可写模式下,此参数是必需的;[RESET resetFunction]
:用于重置属性值的公共成员函数的名称;[NOTIFY notifySignal]
:当属性值改变时发出的信号的名称;[DESIGNABLE bool] [SCRIPTABLE bool] [STORED bool] [USER bool] [CONSTANT] [FINAL] [REQUIRED]
:一些额外的选项,可以根据需要选择性地添加;
在 Qt Creator 中使用 Q_PROPERTY
的示例代码:
1、创建一个新的 widget 应用程序项目;
2、在项目中创建一个新的类,将其命名为 Person
,继承自 QObject
类,打开 person.h
文件,并添加以下代码:
这里,我们添加了两个属性:
name
和age
,name
属性是一个字符串,age
属性是一个整数,对于每个属性,我们都指定了它的读取器和写入器,以及它们相应的信号;
#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、在 person.cpp
文件,并添加以下代码:
这里,我们实现了
Person
类中的属性方法,它们都非常简单:getName()
和getAge()
分别返回m_name
和m_age
成员变量的值,setName()
和setAge()
根据参数设置m_name
和m_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);
}
}
4、现在我们可以在主函数中使用这个 Person
类了,打开 widget.cpp
文件,并添加以下代码:
这里,我们创建了一个新的
Person
对象,使用setProperty()
方法设置了它的name
和age
属性的值,并对其进行了查询,然后,我们使用setName()
和setAge()
方法手动更改属性值,并触发了相应的信号,最后,我们将该对象删除以释放资源;
#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;
}