如何从另一个线程的 cpp 代码同步调用 qml 信号处理程序

How to call qml signal handler synchronously from cpp code from another thread?

本文关键字:调用 同步 qml 信号处理 程序 代码 cpp 另一个 线程      更新时间:2023-10-16

我知道通常你不会按照我的要求去做。我知道这两层应该是分开的,并通过信号/插槽机制连接,如果我们处理线程,这可能是异步的。

理解了这一点,我仍然需要从 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调用信号处理程序的正确语法,或者根本不可能?有什么想法吗?

您可以使用

C++对象的上下文将其传递给 QML。

qmlviewer.rootContext()->setContextProperty("backend", backend);

QML方面:

Connections {
    target: backend
    onCallQmlHandler: {
        // do something right now
    }
}

从后端对象发出callQmlHandler时,将执行处理程序。但是Connections对象可能会创建排队的连接,因此您可以实现自己的DirectConnections。在这篇文章的最后,你有一个实现。

然而,QML是由QML引擎超越的,我认为它是由单个线程运行的,所以你可能会遇到一个更大的问题,除非你真的知道你在做什么!