动态属性系统
在标准C++中,为了保证封装性,我们经常声明一个私有变量,然后声明两个公有函数,即set函数和get函数。在Qt中我们可以使用宏Q_PROPERTY()来实现这些。一个属性可以使用常规函数QObject::property()和QObject::setProperty()进行读写,不用知道属性所在类的任何细节,除了属性的名字。
Q_PROPERTY()原型:
具体实现
//属性设置的头文件.h
class MyProperity : public QObject
{
Q_OBJECT
Q_PROPERTY(QString mask READ mask WRITE setMask NOTIFY maskChanged)
public:
explicit MyProperity(QObject *parent = nullptr);
QString mask()const; //读属性
void setMask(QString maskNum);//设置属性,在cpp中实现
signals:
void maskChanged(QString str);//属性变更时发射的信号
public slots:
private:
QString m_mask; //保存属性值
};
在另外的一个头文件中添加槽方法用来响应发射的方法
cpp添加头文件:添加槽方法定义
main方法:
设置和读取可以通过本对象,也可以通过父类指针:
①myp1->mask();//直接利用对象进行读取数据
②myp1->setMask(“200000万个口罩”);//直接利用对象指针进行改变
③obj->property(“mask”);//利用父类指针进行读取
④obj->setProperty(“mask”,“3000000万个口罩”);//利用父类指针进行改值,同样会发射信号
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
MyProperity *myp1=new MyProperity;
MyProperity *myp2=new MyProperity;
QObject *obj=myp1;
QObject *obj2=myp2;
connect(myp1,SIGNAL(maskChanged(QString&)),this,SLOT(maskNum(QString&)));//建立连接
myp1->setMask("200000万个口罩");//直接利用对象指针进行改变
qDebug()<<"mpy1 mask number:"<<myp1->mask();//直接利用对象进行读取数据
qDebug()<<"obj->mpy1 mask number:"<<obj->property("mask");//利用父类指针进行读取
qDebug()<<"obj->mpy1 mask number:"<<obj->property("mask").toString();//利用父类指针读取,改变类型
obj->setProperty("mask","3000000万个口罩");//利用父类指针进行改值
qDebug()<<"obj2->mpy2 mask number:"<<obj2->property("mask").toString();
}
运行结果:
总结:
设置了的动态属性会注册到元对象系统中是针对与当前的实例,会添加到QObject中但是不会添加到QMetaObject中,不会实现共享(所以不同的实例有不同的结果mask1和mask2动态属性对象的值不同)