天天看點

關于在Qt裡讓程式休眠一段時間的方法總結

Qt 為何沒有提供 Sleep

論壇上不時見到有人問:

Qt 為什麼沒有提供跨平台的 sleep 函數?

使用平台相關的 Sleep 或 nanosleep 以後,界面為什麼沒有反應?

QThread 中提供了protected 權限的 sleep 函數,如何用到主線程中?

使用 QTest 中的 qSleep,在windows下如何隐藏控制台?

這些問題其實歸結為一點:在主線程中使用這些函數是一種錯誤,這會直接導緻界面無法重新整理,使用者與程式無法互動。

Qt不提供,是因為你不需要在主線程中使用 sleep 函數。

如何讓程式等待一段時間QTime

QTime t; 

t.start(); 

while(t.elapsed()<1000);

這種死循環也是一種常見錯誤用法。但改成正确的還是比較簡單的:

QTime t;  

t.start();  

while(t.elapsed()<1000)  

QCoreApplication::processEvents();  

不停地處理事件,以使得程式保持響應。

QElapsedTimer

這是Qt4.7引入的新的類,和QTime相比,它提供了更快的計算 elapsed 時間的方法。

QElapsedTimer t;  

這是QTest子產品提供的等待函數(QTest::qWait)

下面是其源代碼(和我們前面的代碼很像吧?):

namespace QTest 

inline static void qWait(int ms) 

Q_ASSERT(QCoreApplication::instance()); 

QElapsedTimer timer; 

timer.start(); 

do { 

QCoreApplication::processEvents(QEventLoop::AllEvents, ms); 

QTest::qSleep(10); 

} while (timer.elapsed() < ms); 

...

其實沒什麼魔力,對吧?但是因為它QTest子產品,是以在程式中我們不要使用它。

QEventLoop

配合QTimer使用局部的 eventLoop 也是一個不錯的選擇。例子:

QEventLoop eventloop;  

QTimer::singleShot(100, &eventloop, SLOT(quit()));  

eventloop.exec();  

QTimer 和 QBasicTimer

這兩個和本文沒有什麼直接關系,QTimer估計大家都很熟了。而QBasicTimer估計很少有人用。

與QTimer相比,QBasicTimer更快速、輕量、底層。

與QTimer相比,它不是QObject的派生類。

跨平台的sleep

盡管一開始我們就說了,不需要這個東西。但不排除某種場合下,你确實需要這個東西。如何實作一個跨平台的 sleep 呢?

我們一開始也提到了,QThread類 和 QTest子產品都提供了sleep函數,其實我們隻需要看看他們的源碼就夠了:

QTest 子產品中的函數很簡單(windows下調用Sleep,其他平台調用 nanosleep):

void QTest::qSleep(int ms) 

QTEST_ASSERT(ms > 0); 

#ifdef Q_OS_WIN 

Sleep(uint(ms)); 

#else 

struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 }; 

nanosleep(&ts, NULL); 

#endif 

}

摘自:http://blog.sina.com.cn/s/blog_4888f8810100u9rq.html

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。

本文轉自韓兆新部落格部落格園部落格,原文連結:http://www.cnblogs.com/hanzhaoxin/archive/2012/11/23/2784887.html,如需轉載請自行聯系原作者

繼續閱讀