竹笋

首页 » 问答 » 常识 » 软件特攻队Qt中的反射机制之QPROP
TUhjnbcbe - 2023/6/10 21:00:00
京东运营求职招聘QQ群 http://liangssw.com/bozhu/12746.html

接触过Java的同学肯定知道“反射”这一神器,而所谓的反射,指的是对于任意的一个类,即使在运行状态下,都能知道这个类的所有方法和属性,并可以动态调用这些方法的一种机制。

但是非常遗憾的是,C++本身并不支持反射。不过现如今我们可以通过Qt中的元对象系统,享受反射带来的好处。

要想掌握反射编程的精髓,首先需要掌握QMetaObject,QMetaProperty,QVariant,和Q_PROPERTY。

而这里就先为大家介绍Q_PROPERTY(...)宏的用法。

我们了解到Qt之所以具有反射机制,是由于在编译C++代码之前,先行使用了moc元对象编译器。moc读取了一个C++头文件后,如果发现它具有一个或多个包含Q_OBJECT宏的类声明,它将生成一个包含这些类的元对象代码的C++源文件。而能够支持元对象系统或是反射机制的代码也包含其中。

我们看一个例子:

mystudent.h

#ifndefMYSTUDENT_H#defineMYSTUDENT_H#includeQObject/**学生类*该类继承QObject,并且Q_OBJECT宏被包含在私有段中,以便moc生成可支持属性系统的C++代码*/classMyStudent:publicQObject{Q_OBJECT//id代表属性m_id的名称,类型为QString()//推荐属性使用“m_属性名称”的形式//READ函数使用“get属性名称”的形式//WRITE函数使用“set属性名称”的形式Q_PROPERTY(QStringidREADgetIdWRITEsetId)Q_PROPERTY(QStringnameREADgetNameWRITEsetName)Q_PROPERTY(SexsexREADgetSexWRITEsetSex)//用来生成字符串到枚举值的转换函数Q_ENUMS(Sex)public:enumSex//性别{Man,//男Woman//女};explicitMyStudent(QObject*parent=0);QStringgetId()const;voidsetId(constQStringid);QStringgetName()const;voidsetName(constQStringname);SexgetSex()const;QStringgetSexString()const;voidsetSex(constSexsex);voidsetSex(constQStringsex);private:QStringm_id;//学生idQStringm_name;//学生姓名Sexm_sex;//学生性别};#endif//MYSTUDENT_H

mystudent.cpp

#includeQMetaProperty#includeQVariant#includemystudent.hMyStudent::MyStudent(QObject*parent):QObject(parent){}QStringMyStudent::getId()const{returnm_id;}voidMyStudent::setId(constQStringid){m_id=id;}QStringMyStudent::getName()const{returnm_name;}voidMyStudent::setName(constQStringname){m_name=name;}MyStudent::SexMyStudent::getSex()const{returnm_sex;}QStringMyStudent::getSexString()const{returnproperty(Sex).toString();}voidMyStudent::setSex(constSexsex){m_sex=sex;}voidMyStudent::setSex(constQStringsex){//首先获取元对象指针staticconstQMetaObject*meta=metaObject();//根据属性名称Sex,查找m_sex属性对象QMetaPropertystaticintpropindex=meta-indexOfProperty(sex);staticconstQMetaPropertymp=meta-property(propindex);//QMetaProperty中的方法enumerator可以将字符串转化成枚举值//如果给定的字符串不与任何枚举值匹配,则返回-1QMetaEnummenum=mp.enumerator();constchar*ntyp=sex.toStdString().c_str();m_sex=static_castSex(menum.keyToValue(ntyp));}

main.cpp

#includeQVariant#includemystudent.hintmain(){MyStudentstudent;student.setId(1);student.setName(Tom);student.setSex(MyStudent::Man);Q_ASSERT(student.getSex()==MyStudent::Man);//通过属性名称获取属性值QVariantv=student.property(id);QStringstr=v.toString();Q_ASSERT(1==str);student.setProperty(id,QVariant(2));Q_ASSERT(2==student.getId());student.setSex(Woman);Q_ASSERT(student.getSex()==MyStudent::Woman);}

使用setProperty()和property()可以设置和获取由QPROPERTY宏包含的属性。

最后就运行一下程序,体会下Q_PROPERTY的用法吧。

1
查看完整版本: 软件特攻队Qt中的反射机制之QPROP