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.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.