跨线程从QML调用QObject函数
Calling a QObject function from QML across threads
我正在尝试确定从QML为另一个线程中的QObject调用QObject槽或Q_INVOKABLE方法是如何工作的,以及这样做是否安全。
假设有一个MainThread和ThreadA。QObjectA生活在ThreadA中。QML引擎/gui/所有东西都存在于MainThread中。我使用向QML引擎公开QObjectA
declarativeView->setContextProperty("someObj",ObjectA)
现在在QML文件中,我调用
someObj.someMethod();
其中someMethod是slot或是Q_INVOKABLE。我想知道哪个线程实际执行了这个函数。如果是MainThread,那将是一件坏事,跨线程调用这样的方法将是危险的。然而,如果它是由ThreadA执行的,一切都会好起来的。
基于此文档:http://doc.qt.nokia.com/4.7-snapshot/qtbinding.html,我假设QMetaObject::invokeMethod()用于调用QObject函数。该文件(http://doc.qt.nokia.com/4.7-snapshot/qmetaobject.html#invokeMethod),显示有不同的连接类型可用,就像Qt信号和插槽一样。
我想知道当跨线程从qml调用C++方法时,Qt的qml引擎是否会自动为这种情况选择正确的类型,如果是这样,从qml为其他线程中的对象调用方法是可以接受的做法。
正如不久前显而易见的那样,QML似乎无法跨线程运行。
因此,需要实现一个位于主线程中的C++端中间对象,以便将调用分派到其他线程中的对象。
QML object -> object in a different thread // doesn't work!!!
QML object -> C++ mediator object -> object in a different thread // WORKS!!!
基本上,"超越"线程必须完全发生在C++中,因此需要一个中介对象。
我猜someMethod将在ThreadA中执行,因为对象位于该线程中。
但通常情况下,如果这会产生问题,那么我会做这样的事情。
connect(&threadA,SIGNAL(started()),someObj,SLOT(someMethod());
但要启动ThreadA,我们还需要一个CppObject来链接QML和CPP。
您可以在插槽内使用this->thread();
或QThread::currentThreadId();
来获取插槽正在工作的线程。它将始终是线程,ObjectA是在中创建的(如果没有moveToThread()
)。
Qt引擎将通过确定调用和被调用线程来选择正确的Qt:ConnectionType
。
额外提示:您可以使用GammaRay或ThreadManitizer来查看当前线程之间的直接连接。
QML逻辑是事件驱动的,所有调用都是JavaScript函数的一部分。JS函数可以是事件处理程序(例如UI事件处理程序),也可以在C++代码中的某个地方调用(如果您将它们封装在QScript对象中)。您也可以在JavaScriptWorkerHerad中调用它们。这就是为什么只有你才能提供答案,someObj.someMethod()调用发生在哪里。
- QObject::连接不起作用 - 使用函数语法找不到信号
- 将复制构造函数设置为默认值在继承自 QObject 时不起作用
- 将QMETAMETHOD作为参数传递到使用新的Qobject :: Connect语法的函数
- 如何在 exec 循环停止后正确使用 QSharedPointer 的析构函数<QObject>?
- QObject::使用update()函数连接计时器
- 如果从 QObject 派生的类的构造函数抛出,则将发出 destroy()
- 如果对QObject::connect()使用lambda函数,则使用gcc编译失败
- 无法连接Qt QObject::connect()函数
- 调用移动到Qt中不同线程的QObject函数?
- 从基于QObject的类继承构造函数
- 跨线程从QML调用QObject函数
- 是否可以将基本非 QObject 类的虚函数槽化
- QObject::connect 周围的函数包装器
- Qt 线程,来自 QObject 的析构函数的崩溃移动
- 在 Qt5 中,从 QML 调用公共 QObject 函数Q_INVOKABLE需要吗?
- 如何使用新的QObject::连接语法与函数指针将QSslSocket::错误信号连接到插槽
- 从 QObject 继承类中的 winsock 连接函数
- 定义自己的析构函数,尽管类派生自QObject
- QObject派生的类回调函数到c库
- 使用QObject::connect()时,类型签名是否重要,用于将函数连接到信号