天天看點

qt常見問題

1所有能夠接受和發送消息的class必須存在有消息循環的線程環境中。

2對象的消息處理預設環境是是存在于建立這個對象的線程環境中的。

對于第二點如何了解

比如

subthread::subthread()

{

connect(this,sigA,this,slotA);

}

subthread::run()

{

printf tid

exec();

}

void slotA()

{

 printf 線程id

}

UI_thread()

{

    psub=new subthread();

    psub->start()

    Sleep(5000)

    emit psub->sigA

}

在ui線程中建立了一個線程psub,運作這個線程,等待5s線程運作了以後。執行emit psub->sigA

執行 slotA函數

此時列印的線程id應該是 UI_thread的線程。

因為new的這個行為是在UI線程中執行的,是以預設的消息循環是屬于UI線程的。是以在slotA中執行的操作是屬于UI線程環境中的。

明顯run中的id是subthread的id.此時如果有run中和slotA中同時操作一個變量,那麼就會出現同步問題。

如果需要slotA中的環境在subthread中執行。那麼就用到MoveToThread (this)。這裡的this是psub。

object->MoveToThread(threadA)表示,将目前object對象的親和性歸屬到ThreadA中。也就是讓threadA來處理object的消息循環,

我們隻需要在subthread的構造函數中添加

this->MoveToThread(this)。 表示讓subthread對象使用自己的消息處理線程。這樣就可以了。

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、如果某個子事件循環仍然有效,但其父循環被強制跳出,此時父循環不會立即執行跳出,而是等待子事件循環跳出後,父循環才會跳出。