#include "class_a.h"
Class_A::Class_A(QObject *parent) : QObject(parent)
{
}
int Class_A::add(int a, int b)
{
return a+b;
}
/* 2022-8-25
* 1-QT对象的属性
* 2-对象树
* 3-元对象 Q_OBJECT 信号和槽 没有做介绍
* 4-反射机制 做个了解吧,
* 5-对象转换 主要了解 dynamic_cast 动态转换
*/
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QDebug>
#include <QMetaMethod>
#include "class_a.h" //引入头文件
struct X:public QObject //自定的类型需要继承QObject 才可以使用里面的方法
{
/* explicit X() //这样写也可以就是空参,不影响测试效果
{
qDebug()<<__PRETTY_FUNCTION__;
}
*/
explicit X(QObject *p=nullptr):QObject(p) //可以在初始化时就加入对象树
{
qDebug()<<__PRETTY_FUNCTION__;
}
~X()
{
qDebug()<<__PRETTY_FUNCTION__;
}
};
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
///QT对象的属性
QObject* obj=new QObject();
obj->setProperty("id",1);
qDebug()<<obj->property("id");
obj->setObjectName("obj1"); //设置ObjectName方案1
qDebug()<<obj->objectName();
obj->setProperty("objectName","oob"); //设置ObjectName方案2
qDebug()<<obj->property("objectName").toString();
delete obj;
///QT对象树 (上树的对象,根节点父类delete后,子节点全部自动delete丨对控件来说极大的方便了使用者释放资源)
QObject* root=new QObject();
QObject* root_1=new QObject();
root_1->setObjectName("root_1-");//设置属性
root_1->setParent(root); //设置到父类
QObject* root_2=new QObject();
root_2->setObjectName("root_2-");
root_2->setParent(root_1);
QObject* root_a=new QObject(root);//初始化的时候就可以设置对象树
//QObject* root_a=new QObject(); //注释掉的两句可以合并为上面这一条代码
root_a->setObjectName("root_a-");
//root_a->setParent(root);
QObject* x=new X(); //将一个自定义类设置到对象树,看他会不会执行自己的析构函数
x->setObjectName("x");
x->setParent(root_a); //父类须是QObject
//root->dumpObjectTree(); //打印对象树
delete root;
///元对象 Q_OBJECT 需要用它的特性 很强大
//元对象系统 管理着 元对象数据
///反射机制 做个了解吧,
Class_A* ca=new Class_A();
const QMetaObject * ob=ca->metaObject();
qDebug()<<ob->className()<<" "<<ob->superClass()->className(); //打印 类名 父类名
qDebug()<<ob->constructorCount();//打印有几个构造函数
//Class_A构造函数前要加Q_INVOKABLE 结果: 2 如下
// Class_A(QObject *parent = nullptr);Class_A();
//通过反射去做一些事情 调用类的函数 看看就行 理解还需要时间和实践
Class_A* ca_qm=new Class_A();
int num=ca_qm->add(1,2);
const QMetaObject* qm=ca_qm->metaObject();//获取反射
qDebug()<<qm->className();
//QString name("add(int,int)"); //格式化函数签名
QString name=QMetaObject::normalizedSignature("add(int,int)");
int index=qm->indexOfMethod(name.toStdString().c_str()); //应该返回正数 可惜一致没有搞对
QMetaMethod add=qm->method(index); //绝望的时候在函数前加了Q_INVOKABLE
qDebug()<<index; //手动添加到元数据中 //结果 5
int ret(0);
bool bb=add.invoke(ca_qm,Q_RETURN_ARG(int,ret),Q_ARG(int,1),Q_ARG(int,2));
qDebug()<<ret<<" "<<bb; //3 true
///对象转换 主要了解 dynamic_cast 动态转换
QObject* oobj=new QObject();
Class_A* cc_a=dynamic_cast<Class_A*>(oobj);//动态转换 使用范围更广
Class_A* cc_a1=qobject_cast<Class_A*>(oobj);//静态父类转换 更依赖于qobject
return app.exec();
}