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

时间:2016-02-13 20:57:16

标签: c++ multithreading qt qthread qobject

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

如果我们不动态地实例化QObject然后更改其线程关联,则它不起作用。

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

我遇到的问题是了解Qt是否在我们退出后QObject自动处理QThread内的QThread::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和timer移动到创建的QThread实例并运行我的单独线程。

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

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

1 个答案:

答案 0 :(得分:1)

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