Search code examples
c++qtqthread

How to stop looping thread


I want to stop a looping thread when a signal was emitted so here is my code

void  MyThread::stopWatchingThread()
{
    qDebug()<<"MyThread::stopWatchingThread()";    
    Keep_running=false;
    qDebug()<<"MyThread::stopWatchingThread Keep_running"<<Keep_running;
    ...
}

void MyThread::run()
{
  qDebug()<<"MyThread::run()";
  qDebug()<<"MyThread::run Keep_running"<<Keep_running;  
  while(Keep_running)
    {
     ...
     }
  qDebug()<<"MyThread::run Keep_running"<<Keep_running;
  Keep_running=false;
  qDebug()<<"MyThread::run Keep_running"<<Keep_running;
}

void Watcher::Init()
{
    WatchingThread=new MyThread(this->L_RootToWatch);
    connect(this,SIGNAL(stopmonotiring()),WatchingThread, SLOT(stopWatchingThread()));
...
}
void Watcher::StartWatching()
{
    WatchingThread->start();
}

void Watcher::StopWatching()
{
    emit stopmonotiring();        
}

So every thing goes all right but my problem is that Keep_running never get false value in MyThread::run() after emitting stopWatchingThread and so while loop for ever. What did I miss ? any help will be appreciated.


Solution

  • Don't create threaded classes explicitly in Qt. Instead, create a worker object, move that object to a QThread, then call start() on the QThread. Here's a quick example:

    class Worker : public QObject
    {
      Q_OBJECT
    public:
      Worker( QObject * parent = 0 )
        : QObject( parent )
      {}
    
    public slots:
      void doWork( ... )
      { 
        // do work here
      }
    
      void stopMonitoring()
      { 
        emit finished();
      }
    
    signals:
      void finished();
    };
    
    int main()
    {
      Worker * w = new Worker();
      QThread * thread = new QThread();
      QObject::connect( w, SIGNAL(finished()), thread, SLOT(quit())
      QObject::connect( w, SIGNAL(finished()), w, SLOT(deleteLater())
      QObject::connect( thread, SIGNAL(finished()), thread, SLOT(deleteLater())
      w->moveToThread( thread );
      thread->start();
    
      // some other object emits a signal connected to the 'doWork()' slot.
    }
    

    I omitted some of the standard QApplication boiler-plate, but you have that already if you're using Qt. This should get you started.