Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
341 views
in Technique[技术] by (71.8m points)

qt - Exit QThread when GUI Application exits

I have the following worker class:

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

    void Exit();

signals:
    void Finished();

public slots:
    void OnExecuteProcess();
};

In MediaWorker.cpp

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

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

In my MainWindow I do the following:

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();   

The threading is working properly. When I close the application I terminate the thread in the destructor:

MainWindow::~MainWindow()
{
    delete ui;

    this->mediaWorker->Exit();
}

so Exit() emits the Finished signal which will hopefully delete the qthread and mediaworker class.

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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

You can just ensure that the 'media' object gets deleted while the main window gets destructed by using either QScopedPointer or std::unique_ptr.

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

If the worker thread used for updating the UI it makes sense to attempt to stop the worker thread before the UI objects released in

void MainWindow::closeEvent(QCloseEvent *)
{
   stopWorker();
}

But there is a chance that the main window never gets closeEvent() called before the destruction so we should handle that:

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

   // it also destroys m_mediaObject
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...