When and how to remove QThread in Qt

I found this QThread example from here . He recommends using QObject and QThread, rather than subclassing QThread.

class Worker : public QObject
{
   Q_OBJECT

public slots:
    void doWork() {
        /* ... */
    }
};

QThread *thread = new QThread;
Worker *worker = new Worker;
worker->moveToThread(thread);
thread->start();
QMetaObject::invokeMethod(worker, "doWork", Qt::QueuedConnection);

My first question is when and how to remove a thread?

I tried connecting to 2 slots, myTest and deleteLater. And I set a breakpoint in myTest, it never worked. Therefore, I suspect that there is no ready signal, which means that the thread will not be deleted.

connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
connect(thread, SIGNAL(finished()), this, SLOT(myTest()));

For a work object, I give the finished signal as the last instruction in doWork and connect it to a slot in which I can delete the work object. Is it correct?

Qt Version: 4.6.2

+4
source share
2 answers

, worker , - , finished(), , , , finished() QObject::deleteLater():

connect(workerThread, &WorkerThread::finished, workerThread, &QObject::deleteLater);
+4

thread connect() .

worker finished() .

, myTest(), :

  • worker finished(), connect() thread->quit(), worker->deleteLater() this->deleteLater().
  • Qt::DirectConnection connect().

, , 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();
}

, Qt 5.5.0 Linux, :

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(). , . , .
0

All Articles