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

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

本文关键字:method gt object- vs QMetaObject stuff+params object invokeMethod      更新时间:2023-10-16

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

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线程感兴趣的区域)。这两者的区别是什么?

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

就像deleteLater()一样,当您希望调用"干净地"发生时,在事件循环迭代之间,为了最大限度地减少其他正在进行的操作可能产生的副作用,当您不希望运行任何其他可能对排队操作产生副作用的操作时,或者您希望所有旨在影响操作的操作都已执行时,排队调用是有用的。此外,在删除的情况下,这将删除所有挂起的事件,连接和诸如此类的东西。

直接呼叫会快得多,但你没有安全性。在大多数情况下,你可以很好,这将使最终的问题更难查明。

如果你计划在不同的线程之间做同步,你必须实现你自己的同步,例如一个QMutex,并确保对该对象的所有访问都经过它。这将比使用排队连接快得多。

显然,"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自动决定类型参数是应该排队还是直接,并且可以被程序员重写

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

请在这里阅读连接类型的描述

Qt: QueuedConnection

当控制返回到接收者线程的事件循环时调用槽。