[英]Error when calling quit() on a QCoreApplication within a QThread
[英]Calling quit in destructor doesn't kill the QThread?
我通過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完成之后,將為worker調用QObject::deleteLater
,並為該線程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;
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.