【发布时间】:2016-02-13 20:57:15
【问题描述】:
如果 QObject 被创建为类成员(例如 QWidget),我们尝试将其移至线程,但它不起作用。
如果我们不动态地实例化 QObject 然后更改它的线程亲和性,它就不起作用。
因此需要做的是动态创建QObject,将其所有插槽和信号连接到UI(例如),然后将其移动到单独的线程。由于它是动态分配的,因此即使我们将生成它的函数留在本地(在函数范围内),它仍然存在于内存中。
我遇到的问题是了解 Qt 是否会在我们退出后自动处理驻留在 QThread 内的 QObject(QThread::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)时,我找不到任何有用的东西。
【问题讨论】:
标签: c++ multithreading qt qthread qobject