• QMetaMethod 获取成员函数的元信息


    在上一篇中,我们将的是QMetaEnum类,它可以获得一个类中由Q_ENUM宏或Q_FLAG宏声明的枚举类型的元信息。同样,QMetaMethod类是用来获取成员方法的元信息的一个类。通过该类,我们可以获取到一个成员方法的类型,比如它是信号、槽、方法、还是构造函数;也可以获得方法的完整签名,以及方法所接受的参数类型和参数名字,当然也可以获取方法的返回值类型;还可以使用access()方法获取成员函数的访问权限。当然,最重要的还是invoke()方法,使用该方法我们可以在任意的QObject对象上调用成员函数。

    而要得到一个QMetaMethod类的实例,有如下方法。对于信号,可以使用该类的静态方法fromSignal()来获得相对于该信号的QMetaMethod对象;对于普通成员函数和槽函数,可以使用类的QMetaObject对象来间接获取。分别举例如下:

    方法一

    QMetaMethod destroyedSignal = QMetaMethod::fromSignal(&QObject::destroyed);
    方法二
    QString retVal;
    QByteArray normalizedSignature = QMetaObject::normalizedSignature("compute(QString, int, double)");
    int methodIndex = obj->metaObject()->indexOfMethod(normalizedSignature);
    QMetaMethod method = obj->metaObject()->method(methodIndex);
    method.invoke(obj,
    Qt::DirectConnection,
    Q_RETURN_ARG(QString, retVal),
    Q_ARG(QString, "sqrt"),
    Q_ARG(int, 42),
    Q_ARG(double, 9.7));
    其中,要使用QMetaObject::normalizedSignature()来规范化函数签名,确保方法签名是invoke()所期望的。

    下面,我们以一个实例来使用一下该类:

    新建一个Qt控制台程序,再新建一个QObject的子类,在该类中声明一个槽函数。代码如下:

    #ifndef MYOBJECT_H
    #define MYOBJECT_H

    #include <QObject>

    class MyObject : public QObject
    {
    Q_OBJECT
    public:
    explicit MyObject(QObject *parent = 0);

    public slots:
    int add(int a, int b);
    };

    #endif // MYOBJECT_H


    然后,在main函数中,我们打印出add槽函数的元信息。代码如下:
    #include <QCoreApplication>
    #include <QMetaMethod>
    #include <QDebug>
    #include "myobject.h"

    int main(int argc, char *argv[])
    {
    QCoreApplication a(argc, argv);

    MyObject obj;
    QByteArray normalizedSignature = QMetaObject::normalizedSignature("add(int, int)");
    int methodIndex = obj.metaObject()->indexOfMethod(normalizedSignature);
    QMetaMethod metaMethod = obj.metaObject()->method(methodIndex);
    qDebug() << "Access: " << metaMethod.access();
    qDebug() << "Valid: " << metaMethod.isValid();
    qDebug() << "Index: " << metaMethod.methodIndex();
    qDebug() << "Signature: " << metaMethod.methodSignature();
    qDebug() << "Type: " << metaMethod.methodType();
    qDebug() << "Name: " << metaMethod.name();
    qDebug() << "Parameter names: " << metaMethod.parameterNames();
    qDebug() << "Parameter types: " << metaMethod.parameterTypes();
    qDebug() << "Return type: " << metaMethod.returnType();
    qDebug() << "Type name: " << metaMethod.typeName();

    return a.exec();
    }

    运行结果如下:

    可以结合QMetaMethod中相关的枚举类型定义来理解上面的输出。

    enum Access { Private, Protected, Public }
    enum MethodType { Method, Signal, Slot, Constructor }


    即,该方法的访问权限为public,类型是slot,其他的都很好理解了。
    当然,上面说了,我们可以使用该类的invoke()函数,在已有的对象上,调用该函数。代码如下:

    int result = 0;
    bool bCall = metaMethod.invoke(&obj, Q_RETURN_ARG(int, result), Q_ARG(int, 1), Q_ARG(int, 1));
    if(bCall)
    {
    qDebug() << "1 + 1 = " << result;
    }

    大家可以自行测试一下结果。

    ---------------------
    作者:求道玉
    来源:CSDN
    原文:https://blog.csdn.net/Amnes1a/article/details/69220916
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    ios 手写键盘闪退问题 UIKBBlurredKeyView candidateList
    ios NSURLErrorDomain Code=-1004 "未能连接到服务器。问题
    最牛B的编码套路
    watchOS开发—初步认识
    iOS开发拓展篇—蓝牙之CoreBlueTooth(BLE)
    iOS开发拓展篇—蓝牙之mutipeerConnectivity的使用
    iOS开发拓展篇—蓝牙之GameKit使用
    iOS开发拓展篇—ReactiveCocoa常见操作方法介绍(进阶篇)
    iOS开发拓展篇—ReactiveCocoa介绍(基础篇)
    iOS开发拓展篇—异常处理
  • 原文地址:https://www.cnblogs.com/findumars/p/11161019.html
Copyright © 2020-2023  润新知