Ocsidot
9th August 2012, 12:22
Hello everyone,
I'm not really used to using Qt, but for my work, I'v to do with it :D. I 've tried to make a generic thread Worker for my actions in multithreaded application. Here is my code
ThreadWorker.h
#ifndef _THREADWORKER_H_
#define _THREADWORKER_H_
#include "QtCore/qobject.h"
#include "QtCore/qthread.h"
#include "QtCore/qtimer.h"
class ThreadWorker : public QObject
{
Q_OBJECT
private:
int _frequency;
QTimer _timer;
public:
ThreadWorker(int frequency = 300);
~ThreadWorker();
/*!
\brief Create a worker which call the specified slot in th specified thread
\param thread The thread to use
\param source The object which contains the slot to use
\param slot The slot to use
*/
void createWorker(QThread *thread, const QObject* source, const char *slot);
/*!
\brief Sets the call frequency for the threaded method
\param frequency Frequency in millsecond (default value: 300ms)
*/
void setFrequency(int frequency);
private slots:
void start();
void stop();
public slots:
/*!
\brief a slot to indicates the end of our current work
*/
void terminate();
signals:
void finished();
};
#endif
ThreadWorker.cpp
#include "ThreadWorker.h"
ThreadWorker::ThreadWorker(int frequency): _frequency(frequency), _timer(this)
{}
ThreadWorker::~ThreadWorker()
{
terminate();
}
void ThreadWorker::createWorker(QThread *thread, const QObject* source, const char *slot)
{
connect(&_timer, SIGNAL(timeout()), source, slot, Qt::DirectConnection);
connect(thread, SIGNAL(started()), this, SLOT(start()), Qt::DirectConnection);
connect(this, SIGNAL(finished()), thread, SLOT(quit()), Qt::DirectConnection);
connect(this, SIGNAL(finished()), this, SLOT(stop()), Qt::DirectConnection);
moveToThread(thread);
}
void ThreadWorker::setFrequency(int frequency)
{
_frequency = frequency;
}
void ThreadWorker::start()
{
_timer.setInterval(_frequency);
_timer.start();
}
void ThreadWorker::stop()
{
if(_timer.isActive())
{
_timer.stop();
}
}
void ThreadWorker::terminate()
{
if(_timer.isActive())
{
emit finished();
}
}
And here is the code which use the ThreadWorker
#include "ThreadWorker.h"
class MyObject : public QObject
{
Q_OBJECT
private
QThread _thread;
ThreadWorker _worker;
public:
MyObject();
~MyObject();
void start();
void stop();
public slots:
void process();
};
MyObject::MyObject(): _thread(this)
{}
MyObject::~MyObject()
{
if(_thread.isRunning())
{
_worker.terminate();
_thread.wait(500);
}
}
void MyObject::start()
{
if(_thread.isRunning())
{
return;
}
_worker.createWorker(&_thread, this, SLOT(process()));
_thread.start();
}
void MyObject::process()
{
//do something
}
void MyObject::stop()
{
_worker.terminate();
}
I run this code in unit tests with QTest library and I use the macro QTEST_MAIN.
The execution seems fine until the following error:
Program: …
Module: 4.7.4
File: global\qglobal.cpp
Line:
ASSERT failure in QCoreApplication::sendEvent: “Cannot send events to objects owned by a different thread. Current thread 3f6a90.
Receiver ‘’ (of type ‘ThreadWorker’) was created in thread 12ef5câ€, file kernel\qcoreapplication.cpp, line...
I do not really see where it comes from :/. Only thing is that this does not occur if I do not put this line moveToThread (thread), however, in this case, the slot process() is never called.
Does anyone have any idea what I am doing wrong?
Thank you in advance for any help you can provide me
ps: Sorry if my english is not correct :/
I'm not really used to using Qt, but for my work, I'v to do with it :D. I 've tried to make a generic thread Worker for my actions in multithreaded application. Here is my code
ThreadWorker.h
#ifndef _THREADWORKER_H_
#define _THREADWORKER_H_
#include "QtCore/qobject.h"
#include "QtCore/qthread.h"
#include "QtCore/qtimer.h"
class ThreadWorker : public QObject
{
Q_OBJECT
private:
int _frequency;
QTimer _timer;
public:
ThreadWorker(int frequency = 300);
~ThreadWorker();
/*!
\brief Create a worker which call the specified slot in th specified thread
\param thread The thread to use
\param source The object which contains the slot to use
\param slot The slot to use
*/
void createWorker(QThread *thread, const QObject* source, const char *slot);
/*!
\brief Sets the call frequency for the threaded method
\param frequency Frequency in millsecond (default value: 300ms)
*/
void setFrequency(int frequency);
private slots:
void start();
void stop();
public slots:
/*!
\brief a slot to indicates the end of our current work
*/
void terminate();
signals:
void finished();
};
#endif
ThreadWorker.cpp
#include "ThreadWorker.h"
ThreadWorker::ThreadWorker(int frequency): _frequency(frequency), _timer(this)
{}
ThreadWorker::~ThreadWorker()
{
terminate();
}
void ThreadWorker::createWorker(QThread *thread, const QObject* source, const char *slot)
{
connect(&_timer, SIGNAL(timeout()), source, slot, Qt::DirectConnection);
connect(thread, SIGNAL(started()), this, SLOT(start()), Qt::DirectConnection);
connect(this, SIGNAL(finished()), thread, SLOT(quit()), Qt::DirectConnection);
connect(this, SIGNAL(finished()), this, SLOT(stop()), Qt::DirectConnection);
moveToThread(thread);
}
void ThreadWorker::setFrequency(int frequency)
{
_frequency = frequency;
}
void ThreadWorker::start()
{
_timer.setInterval(_frequency);
_timer.start();
}
void ThreadWorker::stop()
{
if(_timer.isActive())
{
_timer.stop();
}
}
void ThreadWorker::terminate()
{
if(_timer.isActive())
{
emit finished();
}
}
And here is the code which use the ThreadWorker
#include "ThreadWorker.h"
class MyObject : public QObject
{
Q_OBJECT
private
QThread _thread;
ThreadWorker _worker;
public:
MyObject();
~MyObject();
void start();
void stop();
public slots:
void process();
};
MyObject::MyObject(): _thread(this)
{}
MyObject::~MyObject()
{
if(_thread.isRunning())
{
_worker.terminate();
_thread.wait(500);
}
}
void MyObject::start()
{
if(_thread.isRunning())
{
return;
}
_worker.createWorker(&_thread, this, SLOT(process()));
_thread.start();
}
void MyObject::process()
{
//do something
}
void MyObject::stop()
{
_worker.terminate();
}
I run this code in unit tests with QTest library and I use the macro QTEST_MAIN.
The execution seems fine until the following error:
Program: …
Module: 4.7.4
File: global\qglobal.cpp
Line:
ASSERT failure in QCoreApplication::sendEvent: “Cannot send events to objects owned by a different thread. Current thread 3f6a90.
Receiver ‘’ (of type ‘ThreadWorker’) was created in thread 12ef5câ€, file kernel\qcoreapplication.cpp, line...
I do not really see where it comes from :/. Only thing is that this does not occur if I do not put this line moveToThread (thread), however, in this case, the slot process() is never called.
Does anyone have any idea what I am doing wrong?
Thank you in advance for any help you can provide me
ps: Sorry if my english is not correct :/