我所拥有的是这两个对另一个线程中另一个对象的方法的调用。
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线程感兴趣的区域)。这两者有什么区别?
答案 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 强>
当控制返回到接收者线程的事件循环时,将调用该槽。插槽在接收器的线程中执行。