QMetaObject :: invokeMethod(object,method,stuff + params)vs object-> method()

时间:2015-08-12 06:49:02

标签: c++ qt

我所拥有的是这两个对另一个线程中另一个对象的方法的调用。

QMetaObject::invokeMethod(object, "method", Qt::variousOptionalParameters,
          Q_ARG(int, a), Q_ARG(int, b), Q_ARG(float, c), Q_ARG(QString, d));

object->method(a, b, c,  d);

他们做同样的事情(在这种情况下,至少,他们更新一些GUI元素,以及OpenCV线程感兴趣的区域)。这两者有什么区别?

2 个答案:

答案 0 :(得分:4)

QObject和派生可以具有线程关联,如果有,则可以调度对其方法的排队调用。这可以作为一种简单的同步,其中性能并不重要,显然,您不会在紧密循环中使用排队连接,因为您将获得大量性能损失

就像deleteLater()一样,如果您希望在事件循环迭代之间的清洁"中发生调用,排队调用很有用,以最大限度地减少其他正在进行的操作可能产生的副作用,当您不想要其他任何可能对排队操作产生副作用的运行时,或者您希望所有旨在影响操作的内容都已执行时。此外,在删除的情况下,这将删除任何待处理的事件,连接等等。

直接电话会更快,但你没有安全感。在大多数情况下,你可以没事,这将使最终的问题变得难以确定。

如果您打算在不同的线程之间执行此操作,则必须实现自己的同步,例如QMutex,并确保对该对象的所有访问都通过它。它比使用排队连接快得多。

答案 1 :(得分:2)

显然,“Qt :: QueuedConnection”意味着它是一个排队连接,用于线程间通信

// works across thread, the data is cached internally by Qt, 
// passed down to the receiving thread once it resumes
QMetaObject::invokeMethod(object, "method", Qt::QueuedConnection,
Q_ARG(int, a), Q_ARG(int, b), Q_ARG(float, c), Q_ARG(QString, d)); 

在另一种情况下,这是直接电话

object->method(a, b, c,  d); // object should be within the same thread

您也可以使用Qt :: connect实现它,其中Qt自动确定 type 参数是否应该排队或直接并且可以被程序员覆盖

connect(const QObject * sender, const char * signal, const char * method, Qt::ConnectionType type = Qt::AutoConnection) const

请阅读连接类型here

的说明

<强> Qt的:: QueuedConnection

当控制返回到接收者线程的事件循环时,将调用该槽。插槽在接收器的线程中执行。

相关问题