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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM