如何从另一个线程的 cpp 代码同步调用 qml 信号处理程序?
Posted
技术标签:
【中文标题】如何从另一个线程的 cpp 代码同步调用 qml 信号处理程序?【英文标题】:How to call qml signal handler synchronously from cpp code from another thread? 【发布时间】:2015-02-03 11:37:55 【问题描述】:我知道通常你不会按照我的要求去做。我知道这两层应该是分开的,通过信号/槽机制连接,如果我们处理线程,这可能是异步的。
明白这一点,我仍然需要从 SG 线程同步调用 qml 信号处理程序。 Qml 对象存在于 GUI 线程中,因此从 SG 线程(特别是来自updatePaintNode()
方法)发出信号会导致异步事件。
我已阅读文档,并且从另一个线程的 cpp 同步调用 qml 函数没有问题。例如:
QMetaObject::invokeMethod(this, "myNiceQmlFunction", Qt::DirectConnection);
但是想象一下:
//some.cpp
signal void callQmlHandler();
//some.qml
MyObject
onCallQmlHandler:
// do something right now
我不知道如何通过QMetaObject::invokeMethod
同步调用onCallQmlHandler
。
我没有从代码创建 qml 对象,此时在 cpp 中我无法访问 qml 组件来查找它的子组件,在那里按名称找到 MyObject
并调用它的处理程序(如果可能的话)。无论如何,这不是一个漂亮的方法。
我试图在 QMetaObject 方法中找到信号处理程序,但它不存在。它也不在属性列表中(我检查以防万一,因为信号处理程序的语法类似于属性的语法)
有谁知道我是否错过了通过QMetaObject::invokeMethod
调用信号处理程序的正确语法,或者根本不可能?有什么想法吗?
【问题讨论】:
你检查Connections类型了吗?如前所述,它“可以接收来自其指定目标的任何信号。” 如果invokeMethod(this, "myNiceQmlFunction", ...);
是一个C++语句,而this
是一个C++对象,那么myNiceQmlFunction
怎么能在QML上呢?
@Smasho this 的类型是使用“qmlRegisterType”为 qml 注册的,所以它可以非常简单。我只是在“Type”对象内的 qml“function myNiceQmlFunction() ”中声明。
@BaCaRoZzo 你能澄清一下吗?我不明白 qml Connections
类型如何帮助我从 c++ 调用处理程序。
在您的场景中有一个 c++ 信号并且处理程序在 QML 中。这就是我看到的代码。正如@Smasho 的回答所解释的那样,这是Connections
解决的一个用例。顺便说一句,跨线程的信号槽总是QueuedConnection
ed。
【参考方案1】:
您可以使用其上下文将 C++ 对象传递给 QML。
qmlviewer.rootContext()->setContextProperty("backend", backend);
QML 方面:
Connections
target: backend
onCallQmlHandler:
// do something right now
当您从后端对象发出callQmlHandler
时,您会执行处理程序。
但是Connections
对象可能会创建排队连接,因此您可以实现自己的DirectConnections
。在this 帖子的末尾,您有一个实现。
但是 QML 是由 QML 引擎执行的,我认为该引擎旨在由单线程运行,因此除非您真的知道自己在做什么,否则您可能会遇到更大的问题!
【讨论】:
以上是关于如何从另一个线程的 cpp 代码同步调用 qml 信号处理程序?的主要内容,如果未能解决你的问题,请参考以下文章
如何从另一个 QML 文件调用 QML 文件中定义的 Javascript 函数?