使用connect()
语句删除后面的thread
的方法应该是可行的。
您建议的在worker
完成后删除的方法也应该可行。
但是,为了触发您的槽myTest()
,您需要添加更多代码:
- 当
worker
完成时,使用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.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";
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.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);
}
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();
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()
也会被触发。这可能发生在测试应用程序退出时。但是,需要进行调试以确认这一点,我还没有尝试过。
finished()
信号连接到工作线程,然后再连接到线程自己的deleteLater()
插槽。 - dtech