您稍后使用connect() 语句删除thread 的方法应该有效。
您建议的在 worker 之后删除 finished() 的方法也应该有效。
但是,为了触发您的插槽myTest(),您需要添加更多代码:
- 当
worker 为finished() 时,使用connect() 语句调用thread->quit()、worker->deleteLater() 和this->deleteLater()。
- 在上述
connect() 语句中使用Qt::DirectConnection。
以下是实现上述方案的测试示例,假设你的类名为Tester:
文件worker.h:
#ifndef WORKER_H
#define WORKER_H
#include <QObject>
class Worker : public QObject
{
Q_OBJECT
public:
Worker();
~Worker();
signals:
void finished();
public slots:
void doWork();
};
#endif // WORKER_H
文件worker.cpp:
#include "worker.h"
#include <QDebug>
Worker::Worker()
{
qDebug() << "D/Worker==Worker";
}
Worker::~Worker()
{
qDebug() << "D/Worker==~Worker";
}
void Worker::doWork()
{
qDebug() << "D/Worker==doWork";
// Do work here
emit finished();
}
文件tester.h:
#ifndef TESTER_H
#define TESTER_H
#include <QObject>
class Tester : public QObject
{
Q_OBJECT
public:
Tester();
~Tester();
public:
void startTesting();
public slots:
void myTest();
};
#endif // TESTER_H
文件tester.cpp:
#include "tester.h"
#include "worker.h"
#include <QThread>
#include <QDebug>
Tester::Tester()
{
qDebug() << "D/Tester==Tester";
}
Tester::~Tester()
{
qDebug() << "D/Tester==~Tester";
}
void Tester::startTesting()
{
qDebug() << "D/Tester==startTesting";
QThread * thread = new QThread;
Worker * worker = new Worker;
worker->moveToThread(thread);
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()), Qt::DirectConnection);
connect(thread, SIGNAL(finished()), this, SLOT(myTest()), Qt::DirectConnection);
connect(worker, SIGNAL(finished()), thread, SLOT(quit()), Qt::DirectConnection);
connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()), Qt::DirectConnection);
connect(worker, SIGNAL(finished()), this, SLOT(deleteLater()), Qt::DirectConnection);
thread->start();
QMetaObject::invokeMethod(worker, "doWork", Qt::QueuedConnection);
// "thread" is deleted later.
// "worker" is deleted later.
}
void Tester::myTest()
{
qDebug() << "D/Tester==myTest";
}
文件main.cpp:
#include <QCoreApplication>
#include <QObject>
#include <QDebug>
#include "worker.h"
#include "tester.h"
int main(int argc, char *argv[])
{
qDebug() << "D/TestQThreadNewDelete==main";
QCoreApplication a(argc, argv);
Tester * tester = new Tester;
tester->startTesting();
// "tester" is deleted later in tester->onWorkerFinished().
return a.exec();
}
在 Linux 上使用 Qt 5.5.0 运行此测试应用程序的输出如下:
D/TestQThreadNewDelete==main
D/Tester==Tester
D/Tester==startTesting
D/Worker==Worker
D/Worker==doWork
D/Tester==myTest
D/Worker==~Worker
D/Tester==~Tester
从中我们可以看出:
- 插槽
Tester::myTest() 已触发。
- 因此,信号
QThread::finished() 应该更早发出。
- 同样,插槽
QThread::deleteLater() 也会被触发。这很可能在测试应用程序退出时发生。但是,需要调试才能确认这一点,我没有尝试过。