天天看點

如何讓 Qt 的程式使用 Sleep

論壇上不時見到有人問:

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

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

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

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

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

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

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

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

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

這是QTest子產品提供的等待函數

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

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

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

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

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

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

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

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

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

看QThread的源碼,windows下同樣直接調用Sleep,但非windows的實作比這個就複雜多了:

[cpp] view plaincopy

/*  /internal 

    helper function to do thread sleeps, since usleep()/nanosleep() 

    aren't reliable enough (in terms of behavior and availability) 

*/  

static void thread_sleep(struct timespec *ti)  

{  

    pthread_mutex_t mtx;  

    pthread_cond_t cnd;  

    pthread_mutex_init(&mtx, 0);  

    pthread_cond_init(&cnd, 0);  

    pthread_mutex_lock(&mtx);  

    (void) pthread_cond_timedwait(&cnd, &mtx, ti);  

    pthread_mutex_unlock(&mtx);  

    pthread_cond_destroy(&cnd);  

    pthread_mutex_destroy(&mtx);  

}  

void QThread::sleep(unsigned long secs)  

    struct timeval tv;  

    gettimeofday(&tv, 0);  

    struct timespec ti;  

    ti.tv_sec = tv.tv_sec + secs;  

    ti.tv_nsec = (tv.tv_usec * 1000);  

    thread_sleep(&ti);  

}  

轉載自:http://blog.csdn.net/dbzhang800/article/details/6300425

繼續閱讀