How create paralles threads in Qt? - c++

I created a Worker class for manager threads in Qt.
#include <QThread>
#include <QProcess>
#include <QObject>
class Worker_Bis : public QObject
{
Q_OBJECT
public:
Worker_Bis() : flag_running(false), flag_stopping(false){
thread = new QThread();
moveToThread(thread);
connect(thread, SIGNAL(started()), this, SLOT(start()));
connect(thread, SIGNAL(terminated()), this, SLOT(stop()));
connect(this, SIGNAL(finished()), thread, SLOT(quit()));
connect(this, SIGNAL(terminated()), thread, SLOT(quit()));
connect(thread, SIGNAL(finished()), this, SLOT(deleteLater()));
thread->start();
}
~Worker_Bis(){
if (!isRunning())
thread->deleteLater();
flag_stopping = true;
while (isRunning()){}
deleteLater();
}
bool isRunning() { return flag_running; };
bool isStopping() { return flag_stopping; };
virtual int getLoops() { return 1; };
public slots:
void start(){
flag_running = true;
flag_stopping = false;
starting();
emit started();
int exit;
for (int loop = 0; loop < getLoops(); ++loop){
if (isStopping()){
exit = -1;
break;
}
emit startLoop(loop);
exit = exec(loop);
if (exit != 0)
break;
emit finishLoop(loop);
}
finishing(exit);
if (exit == -1)
emit terminated();
else{
emit finished();
if (exit != 0)
emit error(exit);
}
flag_running = false;
};
void stop(){
flag_stopping = true;
stopping();
emit stopped();
};
signals:
void started();
void finished();
void stopped();
void terminated();
void error(int code);
void startLoop(int loop);
void finishLoop(int loop);
protected:
QThread* thread;
bool flag_stopping;
bool flag_running;
virtual void starting() {};
virtual int exec(int loop) { return 0; };
virtual void finishing(int) {};
virtual void stopping() {};
};
And I implemented twos buttons: start and stop. I start a thread clicking in start button and I stop thread clicking in stop button.
void ButtonStartClicked(){
worker = new Worker(myObj);
}
void ButtonStopClicked(){
delete worker;
}
If I click in start button many times, I will get parallel threads. Can I obtain some memory problems clicking in start button many times?

Related

Is the timer being started from another thread?

QThread documentation suggests two ways to make code run in a separate thread. If I subclass QThread and reimplement run(), then I get
QBasicTimer::start: Timers cannot be started from another thread
-
#include <QWidget>
#include <QThread>
#include <QBasicTimer>
#include <QDebug>
#include <QEvent>
#include <QCoreApplication>
class Worker : public QThread
{
Q_OBJECT
int id;
bool m_abort = false;
bool compute = false;
public:
Worker() {}
protected:
void timerEvent(QTimerEvent *event) override {
if (event->timerId() == id) {
compute = true;
} else {
QObject::timerEvent(event);
}
}
public slots:
void abort() {m_abort = true;}
void run() {
qDebug() << QThread::currentThreadId();
QBasicTimer timer;
id = timer.timerId();
timer.start(1000, this);
forever {
if (m_abort) break;
QCoreApplication::processEvents();
if (compute)
qDebug() << "computed";
compute = false;
}
}
};
class MainWidget : public QWidget
{
Q_OBJECT
QThread thread;
Worker* worker;
public:
MainWidget()
{
qDebug() << QThread::currentThreadId();
worker = new Worker;
worker->start();
}
~MainWidget(){worker->abort();}
};
1) Is the timer being started from another thread?
2) Why I don't get that warning when QBasicTimer is replaced by QTimer?
3) Why I don't get that warning when using moveToThread?
#include <QWidget>
#include <QThread>
#include <QBasicTimer>
#include <QDebug>
#include <QEvent>
#include <QCoreApplication>
class Worker : public QObject
{
Q_OBJECT
QBasicTimer* timer;
bool m_abort = false;
bool compute = false;
public:
Worker() {}
protected:
void timerEvent(QTimerEvent *event) override {
if (event->timerId() == timer->timerId()) {
compute = true;
} else {
QObject::timerEvent(event);
}
}
public slots:
void abort() {m_abort = true;}
void run() {
timer = new QBasicTimer;
timer->start(1000, this);
forever {
if (m_abort) break;
QCoreApplication::processEvents();
if (compute)
qDebug() << "computed";
compute = false;
}
}
};
class MainWidget : public QWidget
{
Q_OBJECT
QThread thread;
Worker* worker;
public:
MainWidget()
{
worker = new Worker;
worker->moveToThread(&thread);
connect(this, &MainWidget::start, worker, &Worker::run);
thread.start();
emit start();
}
~MainWidget(){worker->abort(); thread.quit(); thread.wait();}
signals:
void start();
};
Regarding the first (non-moveToThread) example...
A quick look at the Qt source for QBasicTimer::start shows the following...
void QBasicTimer::start(int msec, QObject *obj)
{
QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance();
// ...
if (Q_UNLIKELY(obj && obj->thread() != eventDispatcher->thread())) {
qWarning("QBasicTimer::start: Timers cannot be started from another thread");
return;
}
So it expects its second argument obj to have a thread affinity equal to the current thread.
In your Worker::run implementation, however, you have...
timer.start(1000, this);
In this context the current thread is the new thread created by the QThread instance but this refers to the QWorker instance created by the MainWidget on the main GUI thread. Hence the warning.
Edit 1:
To the question...
why it works with moveToThread()?
Consider the implementation of the MainWidget ctor...
MainWidget()
{
worker = new Worker;
worker->moveToThread(&thread);
connect(this, &MainWidget::start, worker, &Worker::run);
thread.start();
emit start();
}
By the time Worker::run is called the Worker instance has been moved to the new thread. So when the line...
timer.start(1000, this);
executes, this (which refers to the Worker instance) is on the current thread and the thread affinity test in QBasicTimer::start passes without warning.
Sorry if the above is a bit convoluted but the important thing is to consider the thread affinity of the second arg to QBasicTimer::start: it must be the currently running thread.

GUI lag issue when using thread

This is the code i'm using now the issue is when i press on the pushbutton
the thread is starting and the value in line edit is updating.
but it slows down the GUI overall.
I am learning QThread so implemented this code and facing difficulties in it.
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QThread>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
qDebug()<<"pd1";
work->moveToThread(thread);
connect(work, SIGNAL(finished()), work, SLOT(deleteLater()));
connect(thread, SIGNAL(started()), work, SLOT(process()));
connect(work, SIGNAL(datar(int)), this, SLOT(display(int)));
connect(work, SIGNAL(finished()), thread, SLOT(quit()));
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start();
qDebug()<<"pd2";
}
void MainWindow::display(int i)
{
ui->lineEdit->setText(QString::number(i));
}
void MainWindow::on_pushButton_2_clicked()
{
qDebug()<<"In push button - 2";
for(int i = 0; i < 200; i++)
{
qDebug()<<i;
ui->lineEdit_2->setText(QString::number(i));
}
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <worker.h>
#include <QThread>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void display(int i);
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
void on_pushButton_3_clicked();
void on_pushButton_4_clicked();
private:
Ui::MainWindow *ui;
worker* work = new worker();
QThread* thread = new QThread;
};
worker.cpp
#include "worker.h"
#include <QDebug>
worker::worker(QObject *parent) : QObject(parent)
{
}
void worker::process()
{
int index = 0;
qDebug()<<"In here";
while(true)
{
qDebug("Hello World!");
index += 1;
if(index > 10000)
{
index = 0;
}
emit datar(index);
}
emit finished();
}
worker.h
#ifndef WORKER_H
#define WORKER_H
#include <QObject>
class worker : public QObject
{
Q_OBJECT
public:
explicit worker(QObject *parent = 0);
signals:
void finished();
void datar(int);
public slots:
void process();
};
#endif // WORKER_H
What i wanted was to update the line edit continusoly from thread such that it doesn't affect the GUI performance.
It would be great if you identify the mistake and suggest me the changes to do.
Consider your worker::process implementation...
void worker::process()
{
int index = 0;
qDebug()<<"In here";
while(true)
{
qDebug("Hello World!");
index += 1;
if(index > 10000)
{
index = 0;
}
emit datar(index);
}
emit finished();
}
It emits the datar signal continuously and without any intervening delays. But the signal emitter and receiver are on different threads meaning the signal will be delivered to the receiver via its event queue. So you are basically saturating the GUI thread's event loop with events from the datar signal.
Try putting even a slight delay between signals with something like...
QThread::msleep(10);

QtThread: worker for I/O queue

I'm trying to create my own worker thread for I/O operations. As far as I know the low-level management of the serial port is already done in a separate thread, but I want to put my code in another one to handle timeouts and other middleware stuff.
Here the complete code of my class. Please note it's my first attempt with Qt's multi-threading.
EDIT
The code is updated without sub-classing QThread
#ifndef WORKERSERIAL_H
#define WORKERSERIAL_H
#include <QObject>
#include <QThread>
#include <QQueue>
#include <QMutex>
#include <QTimer>
#include <QDebug>
#include "myserial.h"
class WorkerSerial : public QObject
{
Q_OBJECT
public:
explicit WorkerSerial(QObject *parent = 0) : QObject(parent)
{
m_serial = new MySerial(this);
connect(m_serial, &MySerial::lineReceived, this, &WorkerSerial::serial_LineReceived);
m_stop = false;
}
bool open(QString port, quint32 baudrate) { return m_serial->open(port, baudrate); }
bool isOpen() { return m_serial->serial()->isOpen(); }
QStringList ports() { return m_serial->ports(); }
private:
MySerial *m_serial;
QQueue<QString> m_queue;
QMutex m_mutex;
bool m_stop;
private slots:
void serial_LineReceived(QByteArray line)
{
emit lineReceived(line);
}
signals:
void lineReceived(QByteArray line);
public slots:
void close() { m_serial->close(); }
void send(QString data) { m_mutex.lock(); m_queue.enqueue(data); m_mutex.unlock(); }
void stop() { m_mutex.lock(); m_stop = true; m_mutex.unlock(); }
void run() {
forever {
m_mutex.lock();
if (m_stop)
{
qDebug() << "Closing...";
QTimer::singleShot(0, this, SLOT(close()));
while(m_serial->serial()->isOpen());
m_mutex.unlock();
return;
}
if (!m_queue.isEmpty())
{
QString data = m_queue.dequeue();
qDebug() << m_serial->sendMessage(data.toLocal8Bit(), true);
}
m_mutex.unlock();
}
}
};
#endif // WORKERSERIAL_H
The MySerial class it's a convenient wrapper for QSerialPort. Here the relevant functions:
bool MySerial::open(QString port, quint32 baudrate) {
m_serial->setPortName(port);
if (!m_serial->open(QIODevice::ReadWrite)) return false;
m_serial->setDataBits(QSerialPort::Data7);
m_serial->setParity(QSerialPort::EvenParity);
m_serial->setStopBits(QSerialPort::TwoStop);
m_serial->setBaudRate(baudrate);
m_serial->setFlowControl(QSerialPort::NoFlowControl);
return true;
}
QByteArray MySerial::sendMessage(QByteArray data) {
m_serial->write(data);
return data;
}
Finally, here how I start, use and close the worker:
QThread *workerThread = new QThread;
m_worker = new WorkerSerial;
m_worker->moveToThread(workerThread);
workerThread->start();
QTimer::singleShot(0, m_workerDMX, SLOT(run()));
// ...
m_worker->open("COM1", 250000));
// ...
m_worker->send("Hello World!");
// ...
m_worker->stop();
workerThread->quit();
workerThread->wait(1000);
// Here the application ends
This is the output:
QObject: Cannot create children for a parent that is in a different thread.
(Parent is QSerialPort(0x19882160), parent's thread is QThread(0x187fe598), current thread is WorkerSerial(0x19d4c9b8)
[this error appears when it calls the SendMessage() function]
"Hello World!"
Closing...
QMutex: destroying locked mutex
QThread: Destroyed while thread is still running
[the two errors above are due the singleSlot() isn't executed and thus the serial won't close]
Invalid parameter passed to C runtime function.
Invalid parameter passed to C runtime function.
It seems clear I've messed up something!
Would you help me to understand my mistakes?
Here is (an incomplete) implementation, which should give you an idea of how to simplify your code. Some additional notes are below:
class WorkerSerial : public QObject
{
Q_OBJECT
public:
explicit WorkerSerial(QObject *parent = 0) : QObject(parent)
{
// no need for slot -- connect directly to our signal
connect(&m_serial, &MySerial::lineReceived, this, &WorkerSerial::lineReceived);
}
bool open(QString port, quint32 baudrate) { return m_serial.open(port, baudrate); }
bool isOpen() { return m_serial.serial().isOpen(); }
QStringList ports() { return m_serial.ports(); }
private:
// doesn't need to be a pointer
MySerial m_serial;
signals:
void lineReceived(const QByteArray& line);
public slots:
void close() { m_serial.close(); }
void send(const QByteArray& data)
{
// "lengthy" function call
qDebug() << m_serial.sendMessage(data, true);
}
};
class Sender : public QObject
{
Q_OBJECT
public:
void send(const QByteArray& data) { emit sig_send(data); }
signals:
void sig_send(const QByteArray& data);
}
...
WorkerSerial m_worker;
m_worker.open("COM1", 250000));
QThread m_thread;
m_worker.moveToThread(&m_thread);
m_thread.start();
Sender m_sender;
QObject::connect(&m_sender, &Sender::sig_send, &m_worker, &WorkerSerial::send, Qt::QueuedConnection);
m_sender.send("Hello World!");
m_thread.quit();
m_thread.wait();
m_worker.close();
Additional notes:
I've added a Sender class that queues calls to WorkerSerial::send() on a different thread. If you have a signal in your code, which triggers calls to WorkerSerial::send() you don't need this class.
Once you move m_worker to another thread, it is unsafe to access any of its methods, unless (a) they are guaranteed to be thread-safe; or (b) you serialize (protect) access to m_serial with a mutex.
NOTE: this is not a fully working solution (yet). But I think it's better to post it as an answer than add another piece of code in the original question.
I managed to a different approach. Perhaps it looks weird... but it should have some advantages:
it guarantees the order of the messages to be transmitted
using a QQueue I can know the queue size or other information about
the "variable shadowing" mechanism should allow to safely communicate with the thread
Here the code, below the two last issues:
#ifndef WORKERSERIAL_H
#define WORKERSERIAL_H
#include <QObject>
#include <QThread>
#include <QQueue>
#include <QMutex>
#include <QDebug>
#include "myserial.h"
class WorkerSerial : public QThread
{
Q_OBJECT
public:
explicit WorkerSerial(QObject *parent = 0, int timeout = 0) : QThread(parent), timeout(timeout)
{
quit = false;
command = None;
}
~WorkerSerial()
{
mutex.lock();
quit = true;
mutex.unlock();
wait();
}
void open(QString port, quint32 baudrate)
{
mutex.lock();
this->port = port;
this->baudrate = baudrate;
command = Open;
mutex.unlock();
}
void close()
{
mutex.lock();
command = Close;
mutex.unlock();
}
void stop()
{
mutex.lock();
command = Quit;
mutex.unlock();
}
private:
enum Commands
{
None,
Open,
Close,
Quit
};
QQueue<QString> m_queue;
QMutex mutex;
int timeout;
int command;
QString port;
int baudrate;
QString request;
bool quit;
signals:
void portStateChanged(bool isOpen);
void lineReceived(QByteArray line);
public slots:
void send(QString data)
{
mutex.lock();
m_queue.enqueue(data);
mutex.unlock();
}
void run()
{
MySerial serial;
QString _port;
int _baudrate;
int _timeout;
QString _request = "";
int _command = None;
connect(&serial, &MySerial::lineReceived, this, &WorkerSerial::lineReceived);
mutex.lock();
_timeout = timeout;
mutex.unlock();
forever {
mutex.lock();
_command = command;
command = None;
if (!m_queue.isEmpty()) _request = m_queue.dequeue();
mutex.unlock();
switch (_command) {
case Open:
mutex.lock();
_port = port;
_baudrate = baudrate;
mutex.unlock();
if (serial.open(_port, _baudrate)) emit portStateChanged(true);
else portStateChanged(false);
break;
case Close:
serial.close();
emit portStateChanged(serial.serial()->isOpen());
break;
case Quit:
serial.close();
return;
break;
default:
break;
}
if (!_request.isEmpty())
{
qDebug() << serial.sendMessage(_request.toLocal8Bit(), true);
_request = "";
}
msleep(1);
}
}
};
#endif // WORKERSERIAL_H
Here how to use it:
WorkerSerial *worker = new WorkerSerial(this);
connect(worker , &WorkerSerial::lineReceived, this, &MainWindow::lineReceived);
connect(worker , &WorkerSerial::portStateChanged, this, &MainWindow::portStateChanged);
worker->start();
// ..
worker->open("COM2", 250000);
worker->send("Hello World");
// ..
worker->stop();
worker->wait(1000);
It "works" but there are two main issues:
the serialport is opened but the data are not actually transmitted. The MySerial class is working because if I do the following, bypassing the WorkerSerial:
MySerial serial;
serial.open("COM2", 250000);
serial.sendMessage("Hello World!", true);
the data is sent! Hence there is still something wrong in my WorkerSerial.
due to the forever loop, I need to insert a small delay, otherwise the CPU will run up to 100% doing nothing.

Qt - Simple example using threads controlled by push buttons

I have been trying to get this simple example using threads activated by pushbuttons to work. It is based off of the solution in the question below:
How to implement frequent start/stop of a thread (QThread)
The main differences between the example solution above and my code below are:
I used a QWidget instead of MainWindow
I changed the name of signals for clarity
My code contains debugging information
I experimented with eliminating the signals created by worker as the didn't appear to do anything
It appears that the start/stop signals are not triggering their corresponding slots, but I am not experienced enough to troubleshoot why.
Additionally, I am unsure of the purpose of the signal:
SignalToObj_mainThreadGUI()
Is that just something that could be used and is not?
I have been trying to get this code to work for some time, so any help would be greatly appreciated.
main.cpp
#include "threadtest.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
ThreadTest w;
w.show();
return a.exec();
}
threadtest.h
#include <QWidget>
#include <QThread>
#include "worker.h"
namespace Ui
{
class ThreadTest;
}
class ThreadTest : public QWidget
{
Q_OBJECT
public:
explicit ThreadTest(QWidget *parent = 0);
~ThreadTest();
signals:
void startWorkSignal();
void stopWorkSignal();
private slots:
void on_startButton_clicked();
void on_stopButton_clicked();
private:
Ui::ThreadTest *ui;
worker *myWorker;
QThread *WorkerThread;
};
threadtest.cpp
#include "threadtest.h"
#include "ui_threadtest.h"
ThreadTest::ThreadTest(QWidget *parent) :
QWidget(parent),
ui(new Ui::ThreadTest)
{
ui->setupUi(this);
myWorker = new worker;
WorkerThread = new QThread;
myWorker->moveToThread(WorkerThread);
connect(this,
SIGNAL(startWorkSignal()),
myWorker,
SLOT(StartWork())
);
connect(this,
SIGNAL(stopWorkSignal()),
myWorker,
SLOT(StopWork())
);
//Debug
this->dumpObjectInfo();
myWorker->dumpObjectInfo();
}
ThreadTest::~ThreadTest()
{
delete ui;
}
void ThreadTest::on_startButton_clicked()
{
qDebug() << "startwork signal emmitted";
emit startWorkSignal();
}
void ThreadTest::on_stopButton_clicked()
{
qDebug() << "stopwork signal emmitted";
emit stopWorkSignal();
}
worker.h
#include <QObject>
#include <QDebug>
class worker : public QObject {
Q_OBJECT
public:
explicit worker(QObject *parent = 0);
~worker();
signals:
void SignalToObj_mainThreadGUI();
//void running();
//void stopped();
public slots:
void StopWork();
void StartWork();
private slots:
void do_Work();
private:
volatile bool running, stopped;
};
worker.cpp
#include "worker.h"
worker::worker(QObject *parent) : QObject(parent), stopped(false),
running(false)
{
qDebug() << "running: " << running;
qDebug() << "stopped: " << stopped;
}
worker::~worker() {}
void worker::do_Work()
{
qDebug() << "inside do Work";
emit SignalToObj_mainThreadGUI();
if (!running || stopped) return;
// actual work here
/*
for (int i = 0; i < 100; i++)
{
qDebug() << "count: " + i;
}
*/
QMetaObject::invokeMethod(this, "do_Work", Qt::QueuedConnection);
}
void worker::StopWork()
{
qDebug() << "inside StopWork";
stopped = true;
running = false;
//emit stopped();
}
void worker::StartWork()
{
qDebug() << "inside StartWork";
stopped = false;
running = true;
//emit running();
do_Work();
}
You should write
WorkerThread->start();
Or you can use the thread of the ThreadTest object instead the WorkerThread (in this case the WorkerThread is needless):
myWorker->moveToThread(thread()); // this->thread
The slots are not triggered, because you have moved myWork to the thread WorkerThread, but didnot run an event loop in that thread. In threadtest.cpp, add
WorkerThread .start();
after
myWorker = new worker;
WorkerThread = new QThread;
myWorker->moveToThread(WorkerThread);

QThread - Call a method of another thread

I'm trying to call a method of another thread (not the Main), using invokeMethod. Unfortunately that makes the application crash as soon as it tries to execute the invokeMethod!
Am I mistaking something?
// main.cpp
#include <QtCore>
#include "entrypointclass.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug() << a.thread()->currentThreadId() << " - Application started.";
EntryPointClass entryPoint;
entryPoint.runInNewThread();
return a.exec();
}
// Entrypoint.h
#ifndef ENTRYPOINTCLASS_H
#define ENTRYPOINTCLASS_H
#include "worker.h"
#include <QtCore>
class EntryPointClass : public QObject
{
Q_OBJECT
public:
EntryPointClass();
~EntryPointClass();
void runInNewThread();
public slots:
void timeoutExpired();
private:
Worker* m_Worker;
QThread* m_Thread;
};
#endif // ENTRYPOINTCLASS_H
// Entrypoint.cpp
#include <QTCore>
#include "entrypointclass.h"
#include "Worker.h"
EntryPointClass::EntryPointClass()
{
qDebug() << "EntryPointClass created";
}
EntryPointClass::~EntryPointClass()
{
qDebug() << "EntryPointClass destroyed";
}
void EntryPointClass::runInNewThread()
{
QThread* m_Thread = new QThread;
Worker* m_Worker = new Worker();
connect(m_Thread, SIGNAL(started()), m_Worker, SLOT(doSomething()));
connect(m_Worker, SIGNAL(finished()), m_Thread, SLOT(quit()));
connect(m_Thread, SIGNAL(finished()), m_Thread, SLOT(deleteLater()));
connect(m_Thread, SIGNAL(finished()), m_Worker, SLOT(deleteLater()));
QTimer* timer = new QTimer;
timer->setSingleShot(true);
//bool bOK = connect(timer, SIGNAL(timeout()), m_Worker, SLOT(closeWorker()), Qt::BlockingQueuedConnection);
connect(timer, SIGNAL(timeout()), this, SLOT(timeoutExpired()));
m_Worker->moveToThread(m_Thread);
m_Thread->start();
timer->start(5000);
}
void EntryPointClass::timeoutExpired()
{
qDebug() << "timeout expired";
if (m_Worker != NULL)
{
QMetaObject::invokeMethod(m_Worker, "closeWorker", Qt::QueuedConnection);
}
}
// Worker.h
#ifndef WORKER_H
#define WORKER_H
#include <QtCore>
class Worker : public QObject
{
Q_OBJECT
public:
Worker();
~Worker();
public slots:
void doSomething();
void closeWorker();
private:
bool m_bAbort;
QMutex m_mutex;
signals:
void finished();
};
#endif // WORKER_H
// Worker.cpp
#include "worker.h"
#include <unistd.h>
#include "QTcore"
Worker::Worker()
: m_mutex()
{
qDebug() << this->thread()->currentThreadId() << "Worker created";
m_bAbort = false;
//qDebug() << QString("Thread %1 - Worker created").arg("");//this->thread()->currentThreadId());
}
Worker::~Worker()
{
qDebug() << this->thread()->currentThreadId() << "Worker destroyed";
}
void Worker::doSomething()
{
while(!m_bAbort)
{
sleep(2);
qDebug() << this->thread()->currentThreadId() << "Do Something!";
}
emit finished();
}
void Worker::closeWorker()
{
qDebug() << this->thread()->currentThreadId() << "closeWorker triggered!";
QMutexLocker mutexLocker(&m_mutex);
m_bAbort = true;
}
Instead of invoking a method directly, try posting a custom event. This will require that you implement an event filter at the target that handles your custom event. Event posting always works as long as an event loop is active in the target thread.
Take a look at this answer here too. Also here.
Hope this helps.