我有一些关于QThread的问题和疑问。 1)当我使用QThread-> quit()时,不会发出finished()信号。 2)如何正确地构建和完成线程的执行?
1)完成信号代码 - 头文件。
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QThread>
class MyThread: public QThread
{
Q_OBJECT
public:
explicit MyThread(QObject *parent = 0);
signals:
public slots:
void finished();
protected:
void run();
};
#endif // MYTHREAD_H
1)CPP文件。
#include "MyThread.h"
MyThread::MyThread(QObject *parent) :
QThread(parent)
{
}
void MyThread::finished()
{
//never gets called...
qDebug() << "Finished.";
}
void MyThread::run()
{
connect(this, SIGNAL(finished()), this, SLOT(finished()), Qt::DirectConnection);
this->exec();
}
我正在构建它:
MyThread *mThread = new MyThread(this); //What does parent do/mean ?
mThread->start();
Sleep(5000); //Windows.
mThread->quit(); //Finish thread.
我甚至不明白Qt :: DirectConnection的作用,我已经阅读了文档,但我真的不知道如何以及何时使用Direct / Queued连接。
刚才我想到了另一个问题。
1)我如何完成并清理自己的线程? (我的意思是,线程应该自行退出并进行清理。)
2)如何正确创建/运行新线程的原因以及原因?
谢谢。
答案 0 :(得分:2)
不要分类QThread
。相反,创建一个工作对象(继承QObject
),创建一个QThread
,然后在工作对象上调用moveToThread()
方法。
class Worker : public QObject
{
Q_OBJECT
public:
Worker( QObject * parent = 0 )
: QObject( parent )
{
connect( this, SIGNAL(done()), \
this, SLOT(deleteLater())
);
}
public slots:
void doWork() { // work, work }
signals:
void done(); // emit this when you're finished with the work
};
// in your main function (or wherever)
QThread * thread = new QThread();
Worker * w = new Worker();
w->moveToThread( thread );
thread->start();
// clean up your thread
QObject::connect( w, SIGNAL(destroyed()), thread, SLOT(quit()) );
QObject::connect( thread, SIGNAL(finished()), thread(deleteLater()) );
// at some point, emit a signal connected to your workers 'doWork()' slot.
// when the work is finished, the worker and thread will both clean themselves up.
编辑:如果我使用旧版本的Qt怎么办?
在最近的Qt版本中,QThread::run()
方法的默认实现是调用exec()
,它启动线程的事件循环。如果您支持较旧版本的Qt,则需要继承QThread以使上述代码正常工作。
class MyThread : public QThread
{
void run() { exec(); }
};
然后,只需使用MyThread
代替QThread
,上述所有内容仍适用。在这种情况下,子类QThread
非常有意义,因为您正在创建一个专门的线程类(当您调用start()
时,它会运行自己的事件循环)。
至于线程清理,以上仍然适用。
QObject::connect( thread, SIGNAL(finished()), thread, SLOT(deleteLater()) );
当你调用MyThread::quit()
时,事件循环将返回,run()
将返回,然后线程对象发出finished()
信号。由于MyThread
对象实际上存在于主事件循环中,因此仍将传递deleteLater()
槽调用。