通过QTimer和QTcpSocket正确使用QThread和moveToThread [英] Using QThread and moveToThread properly with QTimer and QTcpSocket

查看:1119
本文介绍了通过QTimer和QTcpSocket正确使用QThread和moveToThread的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通过阅读此内容博客和其他一些东西,对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()之前创建和设置QTcpSocketQTimer对象.由于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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆