Qt ------ 主事件循環與 QEventLoop


1、事件循環一般用exec()函數開啟。QApplicaion::exec()、QMessageBox::exec()都是事件循環。其中前者又被稱為主事件循環。

事件循環首先是一個無限“循環”,程序在exec()里面無限循環,能讓跟在exec()后面的代碼得不到運行機會,直至程序從exec()跳出。從exec()跳出時,事件循環即被終止。QEventLoop::quit()能夠終止事件循環。

其次,之所以被稱為“事件”循環,是因為它能接收事件,並處理之。當事件太多而不能馬上處理完的時候,待處理事件被放在一個“隊列”里,稱為“事件循環隊列”。當事件循環處理完一個事件后,就從“事件循環隊列”中取出下一個事件處理之。當事件循環隊列為空的時候,它和一個啥事也不做的永真循環有點類似,但是和永真循環不同的是,事件循環不會大量占用CPU資源。

事件循環的本質就是以隊列的方式再次分配線程時間片。

2、事件循環是可以嵌套的,一層套一層,子層的事件循環執行exec()的時候,父層事件循環就處於中斷狀態;當子層事件循環跳出exec()后,父層事件循環才能繼續循環下去。

另外,子層事件循環具有父層事件循環的幾乎所有功能。Qt會把事件送到當前生效的那個事件循環隊列中去,其中包括Gui的各種事件。所以用戶在主線程中執行各種exec()(如QMessageBox::exec(),QEventLoop::exec())的時候,雖然這些exec()打斷了main()中的QApplication::exec(),但是Gui界面仍然能夠正常響應。    

3、如果某個子事件循環仍然有效,但其父循環被強制跳出,此時父循環不會立即執行跳出,而是等待子事件循環跳出后,父循環才會跳出。
4、當GUI主線程中的某個函數,比如NETWORK的某個函數為非阻塞,比如下面的例子:

  1. 1:  QNetworkAccessManager qnam;    
  2. 2:  QNetworkReply *reply = qnam.get(QNetworkRequest(QUrl(...)));    
  3. 3:  QEventLoop loop;    
  4. 4:  QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));    
  5. 5:  loop.exec();     


get函數為非阻塞,立即返回,但是我想等在這里直至收到真正的數據,這里用一個局部的循環,等待事件完成后關閉局部循環。


免責聲明!

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



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