簡體   English   中英

在析構函數中調用quit不會殺死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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM