0

我有一些关于 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)如何正确创建/运行新线程的原因以及为什么?

谢谢你。

4

1 回答 1

2

Don't sub-class QThread. Instead, create a worker object (that inherits QObject), create a QThread, then call the moveToThread() method on your worker object.

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.

Edit: What if I'm using an older version of Qt?

In recent Qt releases, the default implementation of the QThread::run() method is to call exec(), which starts the thread's event loop. If you're supporting an older version of Qt, you do need to subclass QThread in order for the above code to work.

class MyThread : public QThread
{
  void run() { exec(); }
};

Then, just use MyThread instead of QThread, and all of the above still applies. In this case, it makes perfect sense to subclass QThread because you're creating a specialized thread class (one that runs its own event loop when you call start()).

As for thread clean-up, the above still applies.

QObject::connect( thread, SIGNAL(finished()), thread, SLOT(deleteLater()) );

When you call MyThread::quit(), the event loop will return, run() will return, then the thread object emits the finished() signal. Since the MyThread object actually lives in the main event loop, the deleteLater() slot invocation will still be delivered.

于 2013-01-25T16:34:02.650 回答