Qt中运行后台线程不阻塞UI线程的方案

有一个想法,一个客户端,有GUI界面的同时也要向网络服务器发送本地采集的数据,通过网络发送数据的接口是同步阻塞的,需要等待服务器响应数据。

如果不采用后台线程的方案,用主UI线程关联一个定时器QTimer来做定时任务发送,那么GUI界面会由于定时器事件响应的槽函数的阻塞,导致整个GUI的按钮事件在某些时刻无法及时响应,会有卡顿的情况。

所以,后台需要运行一个后台线程,与主线程分离,并且该后台线程需要关联一个自己的QTimer,来做定时任务数据采集。

方案其实可以用QThread来做,首先,做一个Task Class:

 1 #include <QTimer>
 2 #include <QObject>
 3 
 4 class MyTaskClass : public QObject
 5 {
 6     Q_OBJECT
 7 public:
 8     explicit MyClass(QObject *parent = 0)
 9    {
10       m_task_timer.setInterval(5000);
11     
12        connect(&m_task_timer, SIGNAL(timeout()), this,    SLOT(dataCollectionSendTask()));
13 
14     m_task_timer.start();
15    }
16 public slots:
17     void dataCollectionSendTask()
18    {
19      //调用网络接口发送采集完成的数据,发送的服务器
20     }
21 private:
22     QTimer m_task_timer;
23     
24 
25 };

然后创建一个QThread线程,把整个MyTaskClass类的实例move到线程中就可以了:

 1 #include <QtWidgets/QApplication>
 2 #include <QThread>
 3 #include "MyTaskClass.hpp"
 4 
 5 int main(int argc, char *argv[])
 6 {
 7     QApplication a(argc, argv);
 8     
 9     QThread* backgroundThread = new QThread;
10     backgroundThread->start();
11      
12      MyTaskClass *task = new MyTaskClass();
13      task->moveToThread(backgroundThread);
14      
15     MainWindow w;
16     w.show();
17     return a.exec();
18 }

以上代码就不会阻塞GUI线程了。一个后台线程有一个自己的定时器。

references:

https://stackoverflow.com/questions/18958436/how-to-run-a-timer-inside-a-qthread

http://blog.csdn.net/sydnash/article/details/7425947

http://www.cnblogs.com/liushui-sky/p/5833931.html

原文地址:https://www.cnblogs.com/foohack/p/7449614.html