我通过QtCreator运行这段代码。
问题是当我关闭输出窗口时,线程不会死亡。要杀死线程,我必须转到终端并通过找到其 ID 手动杀死它Application output
或使用窗口上的红色方块按钮杀死它。
除非我们按 Alt F4 关闭窗口,否则此应用程序应该永远运行。
源文件 [cpp]:
#include "mainwindow.h"
Controller::Controller(QMainWindow *parent) : QMainWindow(parent)
{
worker_obj.moveToThread(&workerThread);
worker_obj.timerReceivePackets.moveToThread(&workerThread);
connect(this, &Controller::operate, &worker_obj, &Worker::doSomething);
connect(&workerThread, SIGNAL(started()), &worker_obj, SLOT(initialize()));
connect(&worker_obj, &Worker::resultReady, this, &Controller::handleResults);
connect(&workerThread, SIGNAL(finished()), &workerThread, SLOT(deleteLater()));
workerThread.start();
}
Controller::~Controller()
{
workerThread.wait();
workerThread.quit();
workerThread.terminate();
}
页眉 [h]
#ifndef Worker_H
#define Worker_H
#include <QMainWindow>
#include <QObject>
#include <QImage>
#include <QDebug>
#include <QThread>
#include <QTimer>
class Worker : public QObject
{
Q_OBJECT
private:
public:
QTimer timerReceivePackets;
Worker(QObject * parent = 0) {}
~Worker() {}
public slots:
void initialize()
{
connect (&timerReceivePackets, SIGNAL (timeout()),
this, SLOT (doSomething()));
timerReceivePackets.start();
}
void doSomething()
{
while(1)
{
QString result;
/* ... here is the expensive or blocking operation ... */
emit resultReady(result);
}
}
signals:
void resultReady(const QString &result);
};
class Controller : public QMainWindow
{
Q_OBJECT
QThread workerThread;
public:
Worker worker_obj;
Controller( QMainWindow *parent = 0 );
~Controller();
public slots:
void handleResults(const QString &) {}
signals:
void operate(const QString &);
};
#endif // Worker_H
使用QWidget::closeEvent要求worker完成其任务的解决方案。忽略立即窗口关闭(当主窗口有问题时应用程序退出(以正常终止线程,并且仅在工作线程完成后退出应用程序。这样就可以在退出应用程序之前保存线程中执行的昂贵操作的状态。工作线程完成后QObject::deleteLater
将调用 worker 和线程QThread::quit
线程,该线程在完全关闭后触发 deleteLater。
控制器:
class Controller : public QMainWindow
{
Q_OBJECT
public:
explicit Controller(QMainWindow *parent = nullptr)
: QMainWindow(parent), m_worker(new Worker)
{
QThread *thread = new QThread;
m_worker->moveToThread(thread);
connect(thread, &QThread::started, m_worker, &Worker::operate);
connect(m_worker, &Worker::resultReady, this, &Controller::handleResults);
connect(m_worker, &Worker::finished, thread, &QThread::quit);
connect(thread, &QThread::finished, thread, &QObject::deleteLater);
connect(m_worker, &Worker::finished, m_worker, &QObject::deleteLater);
connect(m_worker, &Worker::finished, qApp, &QApplication::quit);
thread->start();
}
virtual ~Controller() {}
public slots:
void handleResults(const QString &result){
qDebug() << result;
}
protected:
void closeEvent(QCloseEvent *event) override
{
m_worker->finish();
event->ignore();
}
private:
Worker *m_worker;
};
工人:
class Worker : public QObject
{
Q_OBJECT
public:
explicit Worker(QObject *parent = nullptr)
: QObject(parent), m_continue(false) {}
virtual ~Worker() {}
public slots:
void operate(){
m_continue = true;
static QString result;
while(m_continue)
{
result.append('a');
QThread::sleep(2);
emit resultReady(result);
}
emit finished();
}
void finish() {
m_continue = false;
}
signals:
void finished();
void resultReady(const QString &result);
private:
bool m_continue;
};