当 GUI 应用程序退出时退出 QThread

Exit QThread when GUI Application exits

我有以下工人class:

class MediaWorker : public QObject
{
    Q_OBJECT
public:
    explicit MediaWorker(QObject *parent = 0);
    ~MediaWorker();

    void Exit();

signals:
    void Finished();

public slots:
    void OnExecuteProcess();
};

在MediaWorker.cpp

void MediaWorker::Exit()
{
    emit Finished();
}

void MediaWorker::OnExecuteProcess()
{
    qDebug() << "Worker Thread: " << QThread::currentThreadId();
}

在我的主窗口中,我执行以下操作:

this->threadMediaWorker = new QThread();
this->mediaWorker = new MediaWorker();
this->timerMediaWorker = new QTimer();
this->timerMediaWorker->setInterval(1000);

this->timerMediaWorker->moveToThread(this->threadMediaWorker);
this->mediaWorker->moveToThread(this->threadMediaWorker);

connect(this->threadMediaWorker, SIGNAL(started()), this->timerMediaWorker, SLOT(start()));
connect(this->timerMediaWorker, &QTimer::timeout, this->mediaWorker, &MediaWorker::OnExecuteProcess);

connect(this->mediaWorker, &MediaWorker::Finished, this->threadMediaWorker, &QThread::quit);
connect(this->mediaWorker, &MediaWorker::Finished, this->mediaWorker, &MediaWorker::deleteLater);
connect(this->threadMediaWorker, &QThread::finished, this->mediaWorker, &QThread::deleteLater);

this->threadMediaWorker->start();   

线程工作正常。当我关闭应用程序时,我终止了析构函数中的线程:

MainWindow::~MainWindow()
{
    delete ui;

    this->mediaWorker->Exit();
}

所以 Exit() 发出 Finished 信号,这有望删除 qthread 和 mediaworker class。

我的问题是这是否是终止线程和媒体工作者的正确方法class?

My question is what is the proper way of terminating both the worker thread and media worker class?

您可以使用 QScopedPointerstd::unique_ptr.

来确保 'media' 对象被删除,而主要的 window 对象被销毁
class MainWindow : public QMainWindow {
     /// ...
     QThread m_workerThread;
     QScopedPointer<MediaWorker> m_pMediaObject;
     /// ...
};

void MainWindows::init()
{
   // ... other initialization skipped ...
   // for dynamic allocation of the object and keeping the track of it
   m_mediaObject.reset(new MediaWorker());
   m_workerThread.moveToThread(m_mediaObject.data());
}

void MainWindow::stopWorker()
{
    if (m_workerThread.isRunning())
    {
        m_workerThread.quit(); // commands Qt thread to quit its loop
                               // wait till the thread actually quits
        m_workerThread.wait(); // possible to specify milliseconds but
                               // whether or not to limit the wait is
                               // another question
    }
}

如果用于更新 UI 的工作线程,在

中释放 UI 对象之前尝试停止工作线程是有意义的
void MainWindow::closeEvent(QCloseEvent *)
{
   stopWorker();
}

但是有可能主 window 在销毁之前从未被调用 closeEvent() 所以我们应该处理这个问题:

MainWindow::~MainWindow()
{
   stopWorker();

   // it also destroys m_mediaObject
}