简体   繁体   English

在析构函数中调用quit不会杀死QThread吗?

[英]Calling quit in destructor doesn't kill the QThread?

I run this code through QtCreator. 我通过QtCreator运行此代码。
Problem is that when I close the output window the thread doesn't die. 问题是,当我关闭输出窗口时,线程不会死。 To kill the thread I have to go to the terminal and kill it manually by finding its ID or use red square button on Application output window to kill it. 要杀死线程,我必须转到终端并通过找到其ID手动杀死它,或使用“ Application output窗口上的红色方形按钮杀死它。

This application is supposed to be running forever unless we press Alt F4 to close the window. 除非我们按Alt F4关闭窗口,否则该应用程序应该永远运行。

Source file [cpp]: 源文件[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();
}

Header [h] 标头[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

Below is a solution using QWidget::closeEvent to ask worker to finish its task. 以下是使用QWidget :: closeEvent要求工作者完成其任务的解决方案。 Immediate window close (application quit when main window is in question) is ignored to terminate thread gracefully and application is exited only after the worker has finished. 忽略 立即关闭窗口 (在主窗口出现问题时退出应用程序) 以优雅地终止线程,并且仅在工作程序完成后退出应用程序。 This makes it possible to save the state of the expensive operation done in the thread before application is exited. 这使得可以在退出应用程序之前保存线程中执行的昂贵操作的状态。 After worker has finished QObject::deleteLater is called for worker, and QThread::quit for the thread which triggers deleteLater for the thread after it's fully shut down. 在worker完成之后,将为worker调用QObject::deleteLater ,并为该线程QThread::quit ,该线程在完全关闭后会触发该线程的deleteLater。

Controller: 控制器:

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;
};

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM