From reading this blog, this blog and some others, Subclassing QThread is bad practice. So I tried to apply this method.
But my problem is that I have a QTimer and a QTcpSocket in the class I want to move to a different thread. Suddenly, it's not as easy as it the examples used. :(
QThread m_commsThread;
m_pICommsHandler = new CommsHandlerIP();
m_pICommsHandler->moveToThread(&m_commsThread);
m_commsThread.start();
And here is the CommsHandlerIP class, methods are not included.
class CommsHandlerIP : public QObject
{
Q_OBJECT
public:
CommsHandlerIP();
~CommsHandlerIP(void);
protected:
QTcpSocket m_TCPSocket;
QTimer m_timer;
}
Issue is that the QTimer and the QTcpSocket (inside CommsHandlerIP class) are in the main thread even if you move CommsHandlerIP. So I can't start the timer or connect the socket.
If I try to moveToThread the QTimer and QTcpSocket (inside the constructor by passing the thread pointer for instance), this become really messy when I leave the app.
What should I do?
Class Instances are created on the calling thread.
QTimer
inherits QObject
.
Each Thread on Qt
can have an event loop if it calls exec()
.
so you want to move QTimer
to an event loop on another thread.
so you should manually move it.
Therefore, delay their creation until after you move the object: -
class CommsHandlerIP : public QObject
{
Q_OBJECT
public slots:
void Initialise();
private:
void Run();
// c++ 11, initialising in headers...
QTimer* m_pTimer = NULL;
QTcpSocket* m_pSocket = NULL;
};
void CommsHandlerIP::Initialise()
{
m_pTimer = new QTimer(this);
m_pSocket = new QTcpSocket(this);
Run();
}
QThread m_commsThread;
m_pICommsHandler = new CommsHandlerIP();
// Note Qt 5 connect style
connect(&m_commsThread, &QThread::started, m_pICommsHandler, &CommsHandlerIP::Initialise);
m_pICommsHandler->moveToThread(&m_commsThread);
m_commsThread.start();
When the thread is started, the CommsHanderIP
Initialise function is called; this is where you should create and setup the QTcpSocket
and QTimer
objects before calling Run()
. As the CommsHandlerIP
is running in the new thread before creating those objects, they will also share the same thread affinity.