驻留在 QThread 内的 QObjects 会自动删除吗?

Posted

技术标签:

【中文标题】驻留在 QThread 内的 QObjects 会自动删除吗?【英文标题】:QObjects residing inside a QThread deleted automatically? 【发布时间】:2016-02-13 20:57:15 【问题描述】:

如果 QObject 被创建为类成员(例如 QWidget),我们尝试将其移至线程,但它不起作用。

如果我们不动态地实例化 QObject 然后更改它的线程亲和性,它就不起作用。

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

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

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

我已经阅读了有关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 实例。然后我将我的用户界面连接到工作人员以及用于每毫秒在工作人员内部触发一些的计时器。之后,我将工作人员和计时器都移动到创建的 QThread 实例并运行我的单独线程。

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

任何人都可以分享他/她的经验吗?我真的不知道接下来要做什么,在互联网上搜索(包括 SO)时,我找不到任何有用的东西。

【问题讨论】:

【参考方案1】:

您可以将其连接到QThread::finished 信号,另请参阅http://doc.qt.io/qt-5/qthread.html#signals。请阅读 Qt 文档,它实际上非常好。 http://doc.qt.io/qt-5/qthread.html#details 包含您需要的所有信息。

【讨论】:

非常感谢。我实际上已经读过这篇文章,但是我完全错过了This signal can be connected to QObject::deleteLater(), to free objects in that thread. :D 至于 Qt 文档 - 当它在那里时,它很好(大部分时间)。

以上是关于驻留在 QThread 内的 QObjects 会自动删除吗?的主要内容,如果未能解决你的问题,请参考以下文章

我不确定为啥我的 QThread 模式会阻塞

驻留在菜单栏中的 Mac 应用程序的技术术语是啥?

Cuda 内核代码驻留在英伟达 GPU 上的啥位置?

QThread 移动到线程。 QThread 中的同步

如何判断我的 NSManagedObject 是不是驻留在只读 NSPersistentStore 中?

是否可以调用驻留在 exe 中的非导出函数?