元对象-初窥

#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();
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值