Qt动态属性系统源码分析

动态属性系统

在标准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动态属性对象的值不同)

猜你喜欢

转载自blog.csdn.net/Jacksqh/article/details/106493605