Pause and Resume a QThread

Jean-Luc picture Jean-Luc · Jan 31, 2012 · Viewed 9.2k times · Source

I've recently began learning about QThreads and I've a program which runs a 4 hours long loop in a separate thread (so that I may continue to use the GUI). What I am after is, something that will pause/suspend the thread when the user clicks pause qpushbutton, and when the user clicks the resume qpushbutton, the program should resume. How may I achieve this?

I was thinking of sending signals from my main class; however, I'm not sure how I can handle them in the thread. Is it possible to handle signals sent from the main class in a thread? Currently, I have the thread emitting signals to the main class, and that works fine, but I'm not sure how to go about sending threads from the main class, and receiving them in the thread.

Answer

Kamil Klimek picture Kamil Klimek · Jan 31, 2012

Ok, so I suggest you make internal thread variable that will be checked in each step of your loop + QWaitCondition to resume it.

  1. Create pause method where you will switch on "pause field" (bool?), don't forget to synchronize it
  2. In your own loop use QWaitCondition (see Qt docs) to pause thread execution
  3. Create resume method where you will switch off "pause field" and wake QWaitCondition

    class MyWorker: public QThread
    {
    private:
        QMutex sync;
        QWaitCondition pauseCond;
        bool pause;
    
    public:
        MyWorker(...): pause(false) {}
    
        void resume()
        {
            sync.lock();
            pause = false;
            sync.unlock();
            pauseCond.wakeAll();
        }
    
        void pause()
        {
            sync.lock();
            pause = true;
            sync.unlock();
        }
    
    protected:
        void run()
        {
            while(someCondition) // gues it's your loop
            {
                 sync.lock();
                 if(pause)
                     pauseCond.wait(&sync); // in this place, your thread will stop to execute until someone calls resume
                 sync.unlock();
    
                 // do your operation
            }
        }
    };