Your method of deleting later thread
using connect()
statement should work.
Your suggested method of deleting later worker
after it is finished()
should also work.
However, in order to trigger your slot myTest()
, you will need to add more code:
- When
worker
is finished()
, use connect()
statements to call thread->quit()
, worker->deleteLater()
, and this->deleteLater()
.
- Use
Qt::DirectConnection
in the above connect()
statements.
Following is a test example to implement the above solution, assuming that your class is named Tester
:
File 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
File 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();
}
File 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
File 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";
}
File 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();
}
The output of running this test application, using Qt 5.5.0 on Linux, is as follows:
D/TestQThreadNewDelete==main
D/Tester==Tester
D/Tester==startTesting
D/Worker==Worker
D/Worker==doWork
D/Tester==myTest
D/Worker==~Worker
D/Tester==~Tester
from which we can see that:
- Slot
Tester::myTest()
was triggered.
- Therefore, signal
QThread::finished()
should have been emitted earlier.
- Similarly, slot
QThread::deleteLater()
would be triggered also. This is likely to happen when the test application exits. However, debugging would be needed in order to confirm this, which I have not tried.