關於在Qt里讓程序休眠一段時間的方法總結


Qt 為何沒有提供 Sleep

論壇上不時見到有人問:

  1. Qt 為什么沒有提供跨平台的 sleep 函數?
  2. 使用平台相關的 Sleep 或 nanosleep 以后,界面為什么沒有反應?
  3. QThread 中提供了protected 權限的 sleep 函數,如何用到主線程中?
  4. 使用 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;
t.start();
while(t.elapsed()<1000)
QCoreApplication::processEvents();

這是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


免責聲明!

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



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