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