stop a loop in object that has been moved to a QThread?
-
Hi
I currently write a communication app that needs to continously receive SPI data.
So I have a mainwindow with a start and stop button. I created a worker class which then contains the SPI communication. To not block the mainwindow I created a QThread and moved the worker class object into it.I can start the doWork() process sucessfuly but how to stop such a loop? Sending signals to the worker class seems not to work since I guess the eventloop is blocked as long as the doWork() loop runs. How to solve that?
mainwindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QWidget> #include <QThread> class MainWindow : public QWidget { Q_OBJECT QThread thread; public: explicit MainWindow(QWidget *parent = nullptr); ~MainWindow(); }; #endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h" #include <QPushButton> #include "worker.h" #include <QThread> MainWindow::MainWindow(QWidget *parent) :QWidget(parent) { QPushButton *pbStart = new QPushButton("START LOOP",this); QPushButton *pbStop = new QPushButton("STOP LOOP",this); pbStop->move(0,40); Worker *worker = new Worker; worker->moveToThread(&thread); connect(&thread, &QThread::finished, worker, &Worker::deleteLater); connect(pbStart, &QPushButton::clicked, worker, &Worker::doWork); thread.start(); } MainWindow::~MainWindow() { thread.quit(); thread.wait(); }
worker.h
#ifndef WORKER_H #define WORKER_H #include <QObject> class Worker :public QObject { Q_OBJECT public: Worker(); ~Worker(); public slots: void doWork(); }; #endif // WORKER_H
worker.cpp
#include "worker.h" Worker::Worker(){} Worker::~Worker(){} void Worker::doWork() { while(true){ // SPI loop communication } };
Can you give me some hints how to solve that?
-
Hi,
If you want to keep the loop then add a variable to break it.
-
@pauledd said in stop a loop in object that has been moved to a QThread?:
Worker::doWork()
As shown, at no time is this function checking the Qt Event loop.
public slots: void doWork(){ ... while(m_running){ // process server UA_Server_run_iterate(m_server, true); // process events like signals QCoreApplication::processEvents(); } ... } void stopWork(){ m_running = false; }
There are signals connected to the slots above to control my server.
-
-
@pauledd
I would recommend using the build-in QThread mechanism to interrupt a thread:public slots: void doWork() { forever() { ... if ( QThread::currentThread()->isInterruptionRequested() ) { return; } ... } }
You can add this check to your SPI loop multiple times but avoid to call it too often, according to the dokumentation.
Add something like this to your MainWindow-Instance:public slots: void cancel() { if( thread.isRunning()) { thread.requestInterruption(); } }
and connect this Slot to some Cancel-Button.