如果我有最标准的使用QThread的代码:
myClass* object = new myClass();
QThread* worker = new QThread();
object->moveToThread(worker);
worker->start();
那么删除 object 的正确方法是什么,以及退出 worker 线程的正确方法?
如果我不删除对象,则会出现内存泄漏。
如果我不退出 worker ,当我关闭应用程序时,会有警告说QThread在它仍在运行时被销毁。
答案 0 :(得分:3)
要删除object
对象,您可以将worker
对象的QThread::finished
信号连接到object
对象的QObject::deleteLater
位置。
要退出线程,您可以在类的析构函数中调用QThread::quit
和QThread::wait
(或者在需要停止线程时)。
MyClass::~MyClass()
{
thread->quit();
thread->wait();
...
}
要删除worker
对象,您只需设置父对象,或将其设为自动成员变量即可。您也可以使用智能指针。
顺便说一下,你的命名约定有点奇怪。您的案例中的QThread
对象不是工作者,它只是管理线程。 myClass
对象将是您案例中的工作者。
答案 1 :(得分:0)
这是一个基本用法:
定义一个工人类:
class MyWorkerClass {
signals:
void Finished();
public slots:
void RunCode(){
//...
// add your code here
//...
emit Finished();
}
}
如何使用您的工人类:
MyWorkerClass * workerObject = new MyWorkerClass();
QThread * workerThread = new QThread();
workerObject->moveToThread(workerThread);
connect(workerThread, &QThread::started, workerObject, &MyWorkerClass::RunCode);
connect(workerObject, &MyWorkerClass::Finished, workerThread, &QThread::quit);
workerThread->start();
workerObject->deleteLater();
答案 2 :(得分:0)
连接 QThread::finished
和QObject::deleteLater
是错误的。如果发出信号QThread::finished
,则意味着线程事件循环不会再次运行,因此不会调用slot QObject::deleteLater
。所以接受的答案是错误的。
最好这样做:
myClass* object = new myClass();
QThread* worker = new QThread(parent);
object->moveToThread(worker);
connect(object, &QObject::destroyed, worker, &QThread::quit, Qt::DirectConnection);
connect(someObject, SIGNAL(stoItSignal()), object, &QObject::deleteLater);
worker->start();
在某些时候可能需要等待踏板(例如当主窗口被销毁时)来清理东西,所以这个声明可能很有用(在这种情况下,上面代码中的Qt::DirectConnection
是强制性的) :
object->deleteLater();
worker->wait(3000);