驻留在 QThread 中的 QObjects 自动删除了吗?

QObjects residing inside a QThread deleted automatically?

如果 QObject 被创建为 class 成员(例如 QWidget)并且我们尝试将其移动到一个线程,它不起作用。

如果我们实例化一个 QObject 不是动态的,然后改变它的线程亲和力,它就不起作用。

所以需要做的是动态创建一个 QObject,将其所有槽和信号连接到 UI(例如),然后将其移动到一个单独的线程。由于它是动态分配的,即使我们离开在本地生成它的函数(在函数范围内),它仍然存在于内存中。

我遇到的问题是了解 Qt 是否在我们退出后自动处理驻留在 QThread 中的 QObjectQThread::quit() 然后等待线程完成在主偶数线程中完成合并)并删除 QThread 对象的实例。

我认为它没有,或者至少这是我在查看 valgrind 的输出时所看到的。所以我的问题是我们如何删除 QObject 其线程亲和性已更改且不再驻留在主线程中的线程?

我已经阅读了有关 QObject::deleteLater() 的文章,所以我相信这是可行的方法。但是我不知道什么时候应用它。

考虑以下代码:

void MyWidget::setup()
{
    thread = new QThread();
    OpenCvWorker *worker = new OpenCvWorker();
    QTimer *workerTrigger = new QTimer();
    workerTrigger->setInterval(1);

    connect(workerTrigger, SIGNAL(timeout()), worker, SLOT(receiveGrabFrame()));
    connect(this, SIGNAL(sendSetup(int)), worker, SLOT(receiveSetup(int)));
    connect(this, SIGNAL(sendToggleStream()), worker, SLOT(receiveToggleStream()));
    connect(ui->pushButtonPlay, SIGNAL(clicked(bool)), this, SLOT(receiveToggleStream()));
    connect(ui->checkBoxEnableBinaryThreshold, SIGNAL(toggled(bool)), worker, SLOT(receiveEnableBinaryThreshold()));
    connect(ui->spinBoxBinaryThreshold, SIGNAL(valueChanged(int)), worker, SLOT(receiveBinaryThreshold(int)));
    connect(worker, SIGNAL(sendFrame(QImage)), this, SLOT(receiveFrame(QImage)));

    workerTrigger->start();
    worker->moveToThread(thread);
//    worker->deleteLater();
    workerTrigger->moveToThread(thread);
//    workerTrigger->deleteLater();

    thread->start();

    emit sendSetup(0);
}

这里我创建了一个worker实例(继承自QObject)和一个QTimer实例。然后我将我的 UI 连接到 worker 以及用于每毫秒触发一些甚至在 worker 内部的计时器。之后,我将工作人员和计时器都移动到创建的 QThread 实例和 运行 我的单独线程。

如您所见,两者都是动态分配的。但是由于范围界定(不能以任何其他方式做到这一点,因为 QObject 在移动到单独的线程时不应该有父级并将其创建为 class 成员基本上就是这样)我想不出释放分配内存的方法。

任何人都可以分享 his/her 经验吗?我真的不知道下一步该怎么做,我在互联网上搜索(包括 SO)时找不到任何有用的东西。

您可以将它连接到 QThread::finished 信号,另请参阅 http://doc.qt.io/qt-5/qthread.html#signals. Please read the Qt documentation, it is actually quite good. http://doc.qt.io/qt-5/qthread.html#details 包含您需要的所有信息。