Qml QObject::moveToThread() perform metaCall
-
Hi,
I have a problem with the following situation:@==QML==
MyObject
{
componentUrl: 'myPath/to/file.qml'
}==C++==
=.h=
class MyObject : public QObject
{
Q_OBJECT
Q_PROPERTY(QString componentUrl ...);
public:
MyObject();
...
signals:
void callJobStart(QObject*);
public slots:
void startOperation();
void threadCompleted(QObject*);
private:
QPointer<QThread> thread_;
QPointer<QObject> obj_;
QString componentUrl;
};class MyJobObj : public QObject
{
...
signals:
void operationDone(QObject*);
public slots:
void performOperation(QObject*);
};=.cpp=
MyObject::MyObject()
: thread_(new QThread(this))
, job_(new MyJobObj())
{
thread_->start();
job_->moveToThread(thread_);
connect(this, SIGNAL(callJobStart(QObject*)), job_, SLOT(performOperation(QObject*)));
connect(job_, SIGNAL(operationDone(QObject*)), this, SLOT(threadCompleted(QObject*)));
}void MyObject::startOperation()
{
QQmlEngine* engine = QQmlEngine::contextForObject(this)->engine();
QQmlComponent component(engine, QUrl::fromLocalFile(componentUrl));
auto obj_ = component_->create(QQmlEngine::contextForObject(worker_));
// perform some modification on obj_ via function
// perform some meta method call on obj_
obj_->setParent(null);
obj_->moveToThread(thread_);
emit callJobStart(obj_);
}void MyObject::threadCompleted(QObject* obj_)
{
// Append the obj_ to child and start using it intyo Qml
}void MyJobObj::performOperation(QObject* obj_)
{
obj_->setParent(this);
// perform computation asynchronoous on obj_
// perform metaCall on obj_
obj_->setParent(null);
obj_->moveToThread(guiThread);
emit operationDone(obj_);
}@I got a problem with the metaCall, crash, both main thread and created thread are inside (see the image attached for an idea of the call stack at crash).
I'm wondering if the QQmlContext and QQmlEngine for the object must be changed or something?
Is that a possible way to pass QObject to another thread, or should I use something different here?
Is a QObject from Qml can be move to other thread or is that forbidden?If anybody can shed some light on this, I would be really be grateful, Thank
Jerome -
-
Found the problem, I was using the engine and context from the main thread for the component instance. Creating a new QQmlEngine and using it's rootContext for the Component instance solve the problem. Probably, this object context will remain valid as long as the Engine owner exist. In my case the MyObject is the new QQmlEngine owner and use the returned object to set some outputs.