invokeMethod

最后更新于:2022-04-02 02:14:10

[TOC] ## invokeMethod - 如果调用的函数耗时较长,同步调用会造成主程序的堵塞。Qt中提供了一个便捷的函数`QMetaObject::invokeMethod` - 该函数就是尝试调用obj的member函数,可以是信号、槽或者Q_INVOKABLE声明的函 - QMetaObject::invokeMethod可以是异步调用,也可以是同步调用。这取决与它的连接方式`Qt::ConnectionType` **函数声明** ``` static bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType, QGenericReturnArgument ret, QGenericArgument val0 = QGenericArgument(Q_NULLPTR), ... QGenericArgument val9 = QGenericArgument()); ``` **调用方式** ``` enum ConnectionType { // 则如果obj与调用者位于同一个线程中,则会同步调用该成员; 否则它将异步调用该成员 AutoConnection, // 则会立即调用该成员。(同步调用) DirectConnection, // 则会发送一个QEvent,并在应用程序进入主事件循环后立即调用该成员。(异步调用) QueuedConnection, // 则将以与Qt :: QueuedConnection相同的方式调用该方法,除了当前线程将阻塞直到事件被传递。使用此连接类型在同一线程中的对象之间进行通信将导致死锁。(异步调用) BlockingQueuedConnection, UniqueConnection = 0x80 }; ``` ## 声明为 Q_INVOKABLE ``` Q_INVOKABLE void setText(QString msg); ``` ## 异步调用注意 当函数的参数有自定义类型时,程序将会报错,因为调用的类型必须是信号、槽,以及Qt元对象系统能识别的类型。可以使用Qt命名类型所提供的`qRegisterMetaType()`来注册自定义类型 ``` //头文件 #include //自定义类型 struct AsynResults { int imgId; QImage image; int result; }; //在类构造时,注册类型 qRegisterMetaType("AsynResults"); //QMetaObject::invokeMethod调用 QMetaObject::invokeMethod(this, "reportImageResultAsync", Q_ARG(AsynResults, asynresults); ``` ## 实例 ``` bool result; //同步调用 QMetaObject::invokeMethod(obj, "func", Qt::DirectConnection, Q_RETURN_ARG(bool, result), Q_ARG(QString, "test"), Q_ARG(int, 100); //异步调用 QMetaObject::invokeMethod(obj, "func", Qt::QueuedConnection, Q_ARG(QString, "test"), Q_ARG(int, 100); ```
';