有時候需要處理一些跟界面無關(guān)的但非常耗時的事情,這些事情跟界面在同一個線程中,由于時間太長,導(dǎo)致界面無法響應(yīng),處于“假死”狀態(tài)。例如:在應(yīng)用程序中保存文件到硬盤上,從開始保存直到文件保存完畢,程序不響應(yīng)用戶的任何操作,窗口也不會重新繪制,從而處于“無法響應(yīng)”狀態(tài),這是一個非常糟糕的體驗 。
? ? ?在這種情況下,有一種方法是使用多線程,即在子線程中處理文件保存,主線程負(fù)責(zé)界面相關(guān)。
? ? ?而如果不想使用多線程,最簡單的辦法就是在文件保存過程中頻繁調(diào)用QApplication::processEvents()。該函數(shù)的作用是讓程序處理那些還沒有處理的事件,然后再把使用權(quán)返回給調(diào)用者。
Qt一般使用QThread::sleep()來延時,但是這樣會阻塞住線程
此時,可以用
QTime delayTime = QTime::currentTime().addMSecs(3000);?? ?//在當(dāng)前時間上增加3S
/* lyh delete -> 避免有拉拽小票沖突 */
while( QTime::currentTime() < delayTime)
?? ?QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
還有另外一種方法,更加簡潔,但是本質(zhì)是一樣的,利用QEventLoop
QEventLoop loop;
QTimer::singleShot(100, &loop, SLOT(quit()));
loop.exec();
場景——run函數(shù):
寫多線程的時候,可以從QThread派生一個線程類,而且要重寫run函數(shù)。重寫run函數(shù)的時候,底部要加一個exec()事件循環(huán)。
void MyThread::run()
{
? ? //希望在線程中完成的操作...
?
? ? exec();//事件循環(huán)
}
跟main函數(shù)一樣,這里必須寫事件循環(huán),否則run函數(shù)執(zhí)行完前面代碼之后會直接結(jié)束,線程就結(jié)束了。
這里穿插一個概念,所謂線程,不是new了一個線程對象就是線程,這個線程對象其實是在父線程中,跟其它對象一樣,new了一個實例而已。它僅僅存在于父線程,它可以作為控制線程的句柄。而真正的線程過程,是run函數(shù)啟動以后,寫在run函數(shù)中的代碼。所以使用繼承QThread并重寫run函數(shù)的方式實現(xiàn)線程時,一定切記,不是所有函數(shù)就一定會在線程中執(zhí)行,除非它被run函數(shù)調(diào)用,或者在run當(dāng)中使用rambda寫匿名槽函數(shù)。而寫匿名槽函數(shù)的時候,接收者千萬別寫this,this指針是指向父線程的線程對象,能作為句柄控制線程,但this隸屬于父線程。所以一旦寫了this是接收者,這個匿名槽函數(shù)會在父線程執(zhí)行。而子線程中創(chuàng)建對象時,也不要指定parent為this。
所以,在run函數(shù)中寫exec,它會阻止run函數(shù)結(jié)束,讓子線程始終等待消息隊列的任務(wù),從而實現(xiàn)利用信號槽進(jìn)行線程通信。
場景——子線程對象
上面說過線程的實現(xiàn),離不開父線程的線程對象,它僅僅是子線程的操作句柄。如果一定要讓一個槽函數(shù)運行于子線程中,可能還少不了要寫個對象再使用movetothread讓它進(jìn)入線程。所以,個人認(rèn)為,寫線程的時候,更好的方法是不要繼承QThread并重寫run函數(shù)。而是把要執(zhí)行的邏輯寫成一個類,實例化以后movetothread,可以確保它一定是在子線程中運行。文章來源:http://www.zghlxwxcb.cn/news/detail-477968.html
MyObject *obj = new MyObject;
QThread *thd = new QThread;
obj->setParent(NULL);
obj->moveToThread(thd);
thd->start();文章來源地址http://www.zghlxwxcb.cn/news/detail-477968.html
到了這里,關(guān)于QT 不阻塞線程,達(dá)到延時的作用的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!