qt的反射用法,直接上代码
Animal.h
#ifndef ANIMAL_H
#define ANIMAL_H
#include<QString>
#include<QObject>
class Animal : public QObject{
//Q_OBJECT,这个为什么注释,因为后面发现一只提示方法重复定义,所以取消父类的标记
public:
explicit Animal(QObject *parent = 0);
//Animal();
virtual QString getName() const=0;
virtual int getAge() const=0;
};
#endif // ANIMAL_H
Animal.cpp
#include "Animal.h"
Animal::Animal(QObject *parent) : QObject(parent)
{
}
Dog.h
#ifndef DOG_H
#define DOG_H
#include"Animal.h"
//#include<QString>
//#include<QObject>
class Dog : public Animal{
Q_OBJECT
Q_PROPERTY (QString name READ getName WRITE setName);
Q_PROPERTY (int age READ getAge WRITE setAge);
Q_ENUMS(Type);
public:
Q_INVOKABLE Dog();
Q_INVOKABLE void setAge(const int age);
Q_INVOKABLE void setName(const QString& name);
Q_INVOKABLE QString getName() const;
Q_INVOKABLE int getAge() const;
enum Type{
ERHA,SHAMOYE,ALASIJI,TIANYUAN
};
Q_INVOKABLE Type getType() const;
Q_INVOKABLE void setType(Type suit);
QString getTypeString();
private:
Type type;
QString name;
int age;
};
Dog.cpp
#include "Dog.h"
Dog::Dog():Animal(nullptr){}
void Dog::setName(const QString &name){
this->name=name;
}
QString Dog::getName() const{
return this->name;
}
int Dog::getAge() const{
return this->age;
}
Dog::Type Dog::getType() const{
return this->type;
}
void Dog::setType(Dog::Type type){
this->type=type;
}
QString Dog::getTypeString(){
QString name;
switch (this->type) {
case ERHA:name="ERHA";
case SHAMOYE:name="SHAMOYE";
case ALASIJI:name="ALASIJI";
case TIANYUAN:name="TIANYUAN";
default:
name="TIANYUAN";
}
return name;
}
void Dog::setAge(const int age){
this->age=age;
}
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "Dog.h"
#include <QDebug>
#include <QQmlContext>
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
//注册
int typeId= qRegisterMetaType<Dog*>();
const QMetaObject *metaObj = QMetaType::metaObjectForType(typeId);
//实例化dog
QObject *obj = metaObj->newInstance();
//获取属性的个数
int propertyCount = metaObj->propertyCount();
//获取方法的个数
int methodCount = metaObj->methodCount();
//输出属性的名字
for(int j = 0;j<propertyCount;j++){
qDebug()<<"propertyName="<< metaObj->property(j).name();
}
//输出类和方法的信息
qDebug()<<"className"<< metaObj->className();
for(int j = 0;j<methodCount;j++){
qDebug()<<"methodName="<< metaObj->method(j).name()<<"methodType"<<metaObj->method(j).typeName()<<"methodSignature"<<metaObj->method(j).methodSignature();
}
//通过执行set方法给属性赋值
QMetaObject::invokeMethod( obj, "setName", Qt::DirectConnection,Q_ARG(QString, "阿黄"));
QMetaObject::invokeMethod( obj, "setAge", Qt::DirectConnection,Q_ARG(int, 3));
QString name;
int age=0;
//get方法取值
QMetaObject::invokeMethod( obj, "getName", Qt::DirectConnection, Q_RETURN_ARG(QString, name ));
QMetaObject::invokeMethod( obj, "getAge", Qt::DirectConnection, Q_RETURN_ARG(int, age ));
qDebug()<<"dogname="<< name<<",dogAge="<<age;
//直接给属性赋值
obj->setProperty("name",QVariant("小黑"));
obj->setProperty("age",QVariant(4));
//obj->setProperty("age",4);
qDebug()<<"dogname="<< obj->property("name").toString()<<",dogAge="<<obj->property("age").toInt();
//dog向上造型
Animal *dog = qobject_cast<Dog*>(obj);
qDebug()<<"dogname="<< dog->getName()<<",dogAge="<<dog->getAge();
//加载qml
QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
//绑定一下dog
engine.rootContext()->setContextProperty("dog",dog);
engine.load(url);
return app.exec();
}
main.qml
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
Window {
visible: true
width: 400
height: 210
color: "#ffffff"
title: qsTr("QuickControlsDemo")
Text {
id: text1
x: 47
y: 35
width: 80
height: 30
text: qsTr("用户名:")
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
font.pixelSize: 14
}
TextField {
id: textField1
x: 137
y: 35
width: 200
height: 30
placeholderText: qsTr("请输入用户名")
}
Text {
id: text2
x: 47
y: 85
width: 80
height: 30
text: qsTr("密 码:")
verticalAlignment: Text.AlignVCenter
font.pixelSize: 14
horizontalAlignment: Text.AlignRight
}
TextField {
id: textField2
x: 137
y: 85
width: 200
height: 30
//echoMode: 2
placeholderText: qsTr("请输入密码")
onTextChanged: {
textField1.text=dog.getName()
}
}
Button {
id: button1
x: 71
y: 145
width: 116
height: 36
text: qsTr("登 录")
onClicked: {
textField2.text=dog.getAge()
}
}
Button {
id: button2
x: 224
y: 145
width: 110
height: 36
text: qsTr("取 消")
}
}
输出结果
propertyName= objectName
propertyName= name
propertyName= age
className Dog
methodName= "destroyed" methodType void methodSignature "destroyed(QObject*)"
methodName= "destroyed" methodType void methodSignature "destroyed()"
methodName= "objectNameChanged" methodType void methodSignature "objectNameChanged(QString)"
methodName= "deleteLater" methodType void methodSignature "deleteLater()"
methodName= "_q_reregisterTimers" methodType void methodSignature "_q_reregisterTimers(void*)"
methodName= "setAge" methodType void methodSignature "setAge(int)"
methodName= "setName" methodType void methodSignature "setName(QString)"
methodName= "getName" methodType QString methodSignature "getName()"
methodName= "getAge" methodType int methodSignature "getAge()"
methodName= "getType" methodType Type methodSignature "getType()"
methodName= "setType" methodType void methodSignature "setType(Type)"
dogname= "阿黄" ,dogAge= 3
dogname= "小黑" ,dogAge= "4"
dogname= "小黑" ,dogAge= 4
总结:
1.整体用法没有什么,都是一些api,主要是用Q_PROPERTY,Q_INVOKABLE标记
2.和java的反射相比体验差了一大截,看了一下这个其实是moc编译生成了中间类
3.本人所用qt版本5.14,版本不一样可能跑不起来,百度的很多版本比较老了,注意下
完毕。