通过QTimer和QTcpSocket正确使用QThread和moveToThread [英] Using QThread and moveToThread properly with QTimer and QTcpSocket
问题描述
通过阅读此内容博客和其他一些东西,对QThread进行子类化是不好的做法.因此,我尝试应用此方法.
From reading this blog, this blog and some others, Subclassing QThread is bad practice. So I tried to apply this method.
但是我的问题是我要移到另一个线程中的类中有一个QTimer和QTcpSocket.突然,它不像所使用的示例那样简单. :(
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();
这是CommsHandlerIP类,不包括方法.
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;
}
问题是,即使您移动CommsHandlerIP,QTimer和QTcpSocket(在CommsHandlerIP类内部)也位于主线程中.所以我无法启动计时器或连接插座.
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.
如果我尝试将QTimer和QTcpSocket(例如,通过传递线程指针传递到构造函数内部)移动到线程,那么当我离开应用程序时,这会变得非常混乱.
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.
我该怎么办?
推荐答案
类实例是在调用线程上创建的.
QTimer
继承QObject
.
如果Qt
上的每个线程都调用exec()
,则可以具有事件循环.
因此您想将QTimer
移至另一个线程上的事件循环.
所以您应该手动移动它.
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();
启动线程时,将调用CommsHanderIP
Initialise 函数;在这里,您应该在调用Run()
之前创建和设置QTcpSocket
和QTimer
对象.由于CommsHandlerIP
在创建这些对象之前正在新线程中运行,因此它们还将共享相同的线程亲和力.
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.
这篇关于通过QTimer和QTcpSocket正确使用QThread和moveToThread的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!