解构对象给出了QCoreApplication :: sendEvent:"无法将事件发送到不同线程拥有的对象

时间:2015-02-26 11:44:24

标签: c++ qt

我的代码太长而无法发布,以下是相关部分:

videoClass::videoClass()
{   
    ...
    QThread* workerThread = new QThread(this);
    camwrk = new cameraWorker(workerThread);
    camwrk->moveToThread(workerThread);
    // There are many cross thread signal slot connections happening between this and the camwrk
}

videoClass::~videoClass()
{   
    ...

    delete camwrk;
    ...
}

cameraWorker::cameraWorker(QThread* workerThread)
{
    _belongingThread = workerThread;
    ...
}

cameraWorker::cameraWorker(QThread* workerThread)
{
    _belongingThread = workerThread;
    ...
}

cameraWorker::~cameraWorker()
{
    _belongingThread->quit();
    _belongingThread->wait();
}

每次_belongingThread-> wait();完了,我收到了消息:

QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread

这里发生了什么?我认为这是使用QThread并完成它的正确方法吗?

1 个答案:

答案 0 :(得分:2)

QThread对象本身属于主线程:

  

重要的是要记住QThread实例存在于实例化它的旧线程中,而不是在调用run()的新线程中。

显然,QThread::wait()是通过事件实现的。由于cameraWorker本身在workerThread而不在videoClass的主题上运行,因此您无法使用它。

话虽如此,你现在的逻辑似乎有点过于复杂。你希望在cameraWorker被破坏时停止线程,并且你想在其父命令被销毁时销毁该工作者:

QThread* workerThread = new QThread(this);

connect(camwrk, SIGNAL(destroyed()), workerThread, SLOT(quit()));
connect(this,   SIGNAL(destroyed()), camwrk,       SLOT(deleteLater()));

如果要在完成执行后删除workerThread,只需连接finished()deleteLater()

connect(workerThread, SIGNAL(finished()),
        workerThread, SLOT(deleteLater()));

但请注意,~videoClass()会调用workerThread的析构函数。确保在对象被销毁之前线程不再运行,或者只是从this删除new QThread(this)以防止所有权。