Qt的QThread文档说要从QThread创建一个类,并实现run方法。
以下是从4.7 Qthread文档中摘录的...
要创建自己的线程,需要从QThread子类化并重新实现run()。例如:
class MyThread : public QThread
{
public:
void run();
};
void MyThread::run()
{
QTcpSocket socket;
// connect QTcpSocket's signals somewhere meaningful
...
socket.connectToHost(hostName, portNumber);
exec();
}
在我创建的每个线程中,我都是这样做的,对于大多数情况,它都可以正常工作(我没有在任何对象中实现moveToThread(this)),这很好用。
我上周遇到了一个问题(通过绕过创建对象的位置来解决),并找到了以下博客文章。基本上这篇文章说子类化QThread不是正确的方式(文档也是错误的)。
这是来自Qt开发者的意见,所以乍一看我很感兴趣,经过进一步思考,我同意他的观点。按照面向对象的原则,你真的只想子类化一个类来进一步增强那个类......而不是仅仅直接使用类的方法...这就是为什么你要实例化的原因......
假设我想将自定义QObject类移动到一个线程中...正确的方法是什么呢?在那篇博客文章中,他“说”他有一个示例...但如果有人能进一步向我解释,我将非常感激!
更新:
由于这个问题受到了如此多的关注,这里是4.8文档的复制粘贴,其中包含实现QThread的“正确”方式。
class Worker : public QObject
{
Q_OBJECT
QThread workerThread;
public slots:
void doWork(const QString ¶meter) {
// ...
emit resultReady(result);
}
signals:
void resultReady(const QString &result);
};
class Controller : public QObject
{
Q_OBJECT
QThread workerThread;
public:
Controller() {
Worker *worker = new Worker;
worker->moveToThread(&workerThread);
connect(workerThread, SIGNAL(finished()), worker, SLOT(deleteLater()));
connect(this, SIGNAL(operate(QString)), worker, SLOT(doWork(QString)));
connect(worker, SIGNAL(resultReady(QString)), this, SLOT(handleResults(QString)));
workerThread.start();
}
~Controller() {
workerThread.quit();
workerThread.wait();
}
public slots:
void handleResults(const QString &);
signals:
void operate(const QString &);
};
我仍然相信指出他们包含一个额外的 Worker::workerThread
成员是值得的,它在他们的示例中是不必要的且从未被使用。删除这一部分后,它就成为了如何在Qt中进行线程处理的合适示例。