Qt元对象系统:QMetaMethod

一、描述

此类提供有关成员函数的元数据。

二、类型成员

1、enum QMetaMethod::Access:此枚举描述了方法的访问级别,遵循C++中使用的约定。

  • Private
  • Protected
  • Public

2、enum QMetaMethod::MethodType:成员函数类型

  • Method:普通成员函数。
  • Signal:信号。
  • Slot:槽。
  • Constructor:构造函数。

三、成员函数

1、QMetaMethod::Access access()

返回此方法的访问级别。

2、【static】template <typename PointerToMemberFunction> QMetaMethod fromSignal(PointerToMemberFunction signal)

返回与给定信号对应的元方法,如果信号不是类的信号,则返回无效的 QMetaMethod。

QMetaMethod destroyedSignal = QMetaMethod::fromSignal(&QObject::destroyed);

3、bool invoke(QObject *object, Qt::ConnectionType connectionType, QGenericReturnArgument returnValue, QGenericArgument val0 = QGenericArgument(nullptr), QGenericArgument val1 = QGenericArgument(), ......)

对 object 对象调用此方法。如果可以调用,则返回 true。如果没有此类成员或参数不匹配,则返回false。

调用可以是同步的,也可以是异步的,具体取决于 connectionType:

  • Qt::DirectConnection:立即调用该成员。
  • Qt::QueuedConnection:一旦应用程序进入主事件循环,就会发布一个 QEvent 并调用该成员。
  • Qt::AutoConnection:如果对象与调用者位于同一线程中,则会同步调用该成员;否则将异步调用该成员。

此方法调用的返回值放在 returnValue 中。如果调用是异步的,则无法计算返回值。

最多可以向这个方法调用传递十个参数(val0、val1、val2、val3、val4、val5、val6、val7、val8和val9)。

QGenericArgument QGenericReturnArgument 是内部帮助程序类。因为可以动态调用信号和槽,所以必须使用 Q_ARG() 和 Q_RETURN_ARG() 宏将参数括起来。

此方法不会测试参数的有效性,object 必须是构造此 QMetaMethod 的 QMetaObject 类的实例。参数的类型必须与方法预期的类型相同,否则行为未定义。

QPushButton 上异步调用 animateClick():

int methodIndex = pushButton->metaObject()->indexOfMethod("animateClick()");
QMetaMethod method = metaObject->method(methodIndex);
method.invoke(pushButton, Qt::QueuedConnection);

对于异步方法调用,参数必须是Qt的元对象系统已知的类型。对于自定义类型,在调用之前需要调用 qRegisterMetaType() 注册数据类型。

同步调用某个对象 obj 上的 QString compute(QString,int,double):

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));

如果没有按指定顺序精确地接受一个QString、一个int和一个double,则调用将失败。

      bool invoke(QObject *object, QGenericReturnArgument returnValue, QGenericArgument val0 = QGenericArgument(0), QGenericArgument val1 = QGenericArgument(), ......)

Qt::AutoConnection 调用此方法。

      bool invoke(QObject *object, Qt::ConnectionType connectionType, QGenericArgument val0 = QGenericArgument(0), QGenericArgument val1 = QGenericArgument(), ......)

如果不关心成员的返回值,则可以使用此重载。

      bool invoke(QObject *object, QGenericArgument val0 = QGenericArgument(0), QGenericArgument val1 = QGenericArgument(), ......)

Qt::AutoConnection 调用此方法,并忽略返回值。

4、bool invokeOnGadget(void *gadget, QGenericReturnArgument returnValue, QGenericArgument val0 = QGenericArgument(nullptr), QGenericArgument val1 = QGenericArgument(), ......)

在使用 Q_GADGET 的对象上调用此方法。如果可以调用成员,则返回 true。如果没有此类成员或参数不匹配,则返回 false。

调用始终是同步的。

此方法调用的返回值放在 returnValue 中。最多可以向这个方法调用传递十个参数(val0、val1、val2、val3、val4、val5、val6、val7、val8和val9)。

此方法不会测试参数的有效性,gadget 必须是构造此 QMetaMethod 的 QMetaObject 类的实例。参数的类型必须与方法预期的类型相同,否则行为未定义。

QObject

class test
{
    Q_GADGET
public:
    test() = default;
    Q_INVOKABLE QString showInfo()
    {
        return "xxxxxxxxxxx";
    }
};

int main(int argc, char *argv[])
{
    test t;
    QByteArray normalizedSignature = test::staticMetaObject.normalizedSignature("showInfo()");
    int funIndex = test::staticMetaObject.indexOfMethod(normalizedSignature);
    QMetaMethod method = test::staticMetaObject.method(funIndex);
    QString retVal;
    qDebug()<<method.invokeOnGadget(&t,Q_RETURN_ARG(QString,retVal));//true
    qDebug()<<retVal;//"xxxxxxxxxxx"
}

      bool invokeOnGadget(void *gadget, QGenericArgument val0 = QGenericArgument(0), QGenericArgument val1 = QGenericArgument(), ......)

为 gadget 调用此方法并忽略返回值。

5、bool isConst()

该方法是否是 const 限定的。

6、bool isValid()

此方法是否有效(可以内省和调用)。

7、int methodIndex()

返回此方法的索引。

8、QByteArray methodSignature()

返回此方法的签名。

class test
{
    Q_GADGET
public:
    test() = default;
    Q_INVOKABLE QString showInfo(int a)
    {
        return "xxxxxxxxxxx";
    }
};

int main(int argc, char *argv[])
{
    test t;
    QByteArray normalizedSignature = test::staticMetaObject.normalizedSignature("showInfo(int)");
    int funIndex = test::staticMetaObject.indexOfMethod(normalizedSignature);
    QMetaMethod method = test::staticMetaObject.method(funIndex);
    qDebug()<<method.methodSignature();//"showInfo(int)"
}

9、QMetaMethod::MethodType methodType()

返回此方法的类型(信号、槽或方法)。

10、QByteArray name()

返回此方法的名称。(函数名)

11、int parameterCount()

返回此方法的参数个数。

12、QMetaType parameterMetaType(int index)

返回给定索引的参数的元类型。

13、QList<QByteArray> parameterNames()

返回参数名称列表。

class test
{
    Q_GADGET
public:
    test() = default;
    Q_INVOKABLE QString showInfo(int a,QString b)
    {
        return "xxxxxxxxxxx";
    }
};

int main(int argc, char *argv[])
{
    test t;
    QByteArray normalizedSignature = test::staticMetaObject.normalizedSignature("showInfo(int,QString)");
    int funIndex = test::staticMetaObject.indexOfMethod(normalizedSignature);
    QMetaMethod method = test::staticMetaObject.method(funIndex);
    qDebug()<<method.parameterNames();//QList("a", "b")
}

14、int parameterType(int index)

返回给定索引处的参数类型。返回值是使用 QMetaType 注册的类型,如果该类型未注册,则为 QMetaType::UnknownType

15、QByteArray parameterTypeName(int index)

返回位置索引处类型的名称。

class test
{
    Q_GADGET
public:
    test() = default;
    Q_INVOKABLE QString showInfo(int a,QString b)
    {
        return "xxxxxxxxxxx";
    }
};

int main(int argc, char *argv[])
{
    test t;
    QByteArray normalizedSignature = test::staticMetaObject.normalizedSignature("showInfo(int,QString)");
    int funIndex = test::staticMetaObject.indexOfMethod(normalizedSignature);
    QMetaMethod method = test::staticMetaObject.method(funIndex);
    qDebug()<<method.parameterTypeName(1);//"QString"
}

16、QList<QByteArray> parameterTypes()

返回参数类型列表。

17、QMetaType returnMetaType() 

返回此方法的返回值类型。

18、int returnType()

返回此方法的返回值类型。返回值是使用 QMetaType 注册的类型,如果该类型未注册,则为QMetaType::UnknownType

19、int revision()

如果使用 Q_REVISION 设置了方法的修订版本,则返回方法修订版本,否则返回 0。

20、const char * tag()

返回与此方法关联的标签。标签是由 moc 识别的特殊宏,可以添加有关方法的额外信息。

可以使用标签对方法进行不同的注释,并根据应用程序的特定需要对它们进行处理。

可以通过以下方式在函数声明中添加标签信息:

#ifndef Q_MOC_RUN
    #define MY_CUSTOM_TAG
#endif

class test
{
    Q_GADGET
public:
    test() = default;
    Q_INVOKABLE MY_CUSTOM_TAG QString showInfo(int a,QString b)
    {
        return "xxxxxxxxxxx";
    }
};

int main(int argc, char *argv[])
{
    test t;
    QByteArray normalizedSignature = test::staticMetaObject.normalizedSignature("showInfo(int,QString)");
    int funIndex = test::staticMetaObject.indexOfMethod(normalizedSignature);
    QMetaMethod method = test::staticMetaObject.method(funIndex);
    qDebug()<<method.tag();// MY_CUSTOM_TAG
}

必需使用 #ifndef Q_MOC_RUN 包围定义。

21、const char * typeName()

返回此方法的返回值类型名称。

class test
{
    Q_GADGET
public:
    test() = default;
    Q_INVOKABLE QString showInfo(int a,QString b)
    {
        return "xxxxxxxxxxx";
    }
};

int main(int argc, char *argv[])
{
    test t;
    QByteArray normalizedSignature = test::staticMetaObject.normalizedSignature("showInfo(int,QString)");
    int funIndex = test::staticMetaObject.indexOfMethod(normalizedSignature);
    QMetaMethod method = test::staticMetaObject.method(funIndex);
    qDebug()<<method.typeName();// QString
}

四、宏成员

1、Q_METAMETHOD_INVOKE_MAX_ARGS

等于可用于通过 QMetaMethod::invoke() 执行方法的最大参数个数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值