从 QML QtQuick2 引擎所在的不同线程更新 c++ 模型的行为 运行
Behaviour of a c++ model update from a different thread from which the QML QtQuick2 engine is running
该场景包含以下组件:
- C++ QAbstractItemModel 派生模型class 在主线程中创建
- QML QtQuick2 引擎在主线程中实例化
- Worker boost::thread 在用户交互时从主线程生成
这些组件之间的关系:
- C++ 模型通过使用 qmlRegisterSingletonType<>() 注册的 Q_PROPERTY 类型暴露给 QML 引擎。
- 工作线程通过调用 "emit data_changed(...)"
的方法更新模型
问题:"emit data_changed(...)" 的回调发生在哪个线程?
备注
这个问题的一个关键因素是启动的线程不是 qt 感知的。
我假设工作线程在某些 QObject
上调用信号方法。这是完全线程安全的,并且是一件有效的事情。信号的实现将当前线程与每个插槽的线程进行比较,并确定使用哪种连接(如果连接是自动类型)。
只要您使用自动或排队连接连接到所述信号,插槽就会在其 QObject
实例的 thread()
中被调用。
在哪个线程中调用信号并不重要,该线程是否是 Qt 线程也无关紧要。
如果您为与仿函数的连接提供上下文对象,则仿函数将在上下文对象的线程中执行,因此您可以通过这种方式对对象执行线程安全的仿函数调用:)
例如:
#include <QtCore>
#include <thread>
class Object : public QObject {
Q_OBJECT
public:
Q_SIGNAL void ping();
Q_SLOT void pong() {
qDebug() << "hello on thread" << QThread::currentThread();
qApp.quit();
});
};
int main(int argc, char ** argv) {
QCoreApplication app(argc, argv);
Object obj;
qDebug() << "main thread is" << QThread::currentThread();
QObject::connect(&obj, &Object::ping, &obj, &Object:pong);
QObject::connect(&obj, &Object::ping, []{
qDebug() << "context-free functor invoked on thread" << QThread::currentThread();
});
QObject::connect(&obj, &QObject::ping, &obj, []{
qDebug() << "context-ful functor invoked on thread" << QThread::currentThread();
});
auto thread = std::thread([&obj]{
emit obj.ping();
});
int rc = app.exec();
thread.join();
return rc;
}
#include "main.moc"
该场景包含以下组件:
- C++ QAbstractItemModel 派生模型class 在主线程中创建
- QML QtQuick2 引擎在主线程中实例化
- Worker boost::thread 在用户交互时从主线程生成
这些组件之间的关系:
- C++ 模型通过使用 qmlRegisterSingletonType<>() 注册的 Q_PROPERTY 类型暴露给 QML 引擎。
- 工作线程通过调用 "emit data_changed(...)" 的方法更新模型
问题:"emit data_changed(...)" 的回调发生在哪个线程?
备注
这个问题的一个关键因素是启动的线程不是 qt 感知的。
我假设工作线程在某些 QObject
上调用信号方法。这是完全线程安全的,并且是一件有效的事情。信号的实现将当前线程与每个插槽的线程进行比较,并确定使用哪种连接(如果连接是自动类型)。
只要您使用自动或排队连接连接到所述信号,插槽就会在其 QObject
实例的 thread()
中被调用。
在哪个线程中调用信号并不重要,该线程是否是 Qt 线程也无关紧要。
如果您为与仿函数的连接提供上下文对象,则仿函数将在上下文对象的线程中执行,因此您可以通过这种方式对对象执行线程安全的仿函数调用:)
例如:
#include <QtCore>
#include <thread>
class Object : public QObject {
Q_OBJECT
public:
Q_SIGNAL void ping();
Q_SLOT void pong() {
qDebug() << "hello on thread" << QThread::currentThread();
qApp.quit();
});
};
int main(int argc, char ** argv) {
QCoreApplication app(argc, argv);
Object obj;
qDebug() << "main thread is" << QThread::currentThread();
QObject::connect(&obj, &Object::ping, &obj, &Object:pong);
QObject::connect(&obj, &Object::ping, []{
qDebug() << "context-free functor invoked on thread" << QThread::currentThread();
});
QObject::connect(&obj, &QObject::ping, &obj, []{
qDebug() << "context-ful functor invoked on thread" << QThread::currentThread();
});
auto thread = std::thread([&obj]{
emit obj.ping();
});
int rc = app.exec();
thread.join();
return rc;
}
#include "main.moc"