在Qt中使用定時器有兩種方法,一種是使用QObiect類的定時器;一種是使用QTimer類。定時器的精確性依賴于操作系統(tǒng)和硬件,大多數(shù)平臺支持20ms的精確度。
1.QObject類的定時器
QObject是所有Qt對象的基類,它提供了一個基本的定時器。通過QObject::startTimer(),可以把一個一毫秒為單位的時間間隔作為參數(shù)來開始定時器,這個函數(shù)返回一個唯一的整數(shù)定時器的標識符。這個定時器開始就會在每一個時間間隔"觸發(fā)",直到明確的使用這個定時器的標識符來調用QObject::killTimer()結束。
當定時器觸發(fā)時,應用程序會發(fā)送一個QTimerEvent。在事件循環(huán)中,處理器按照事件隊列的順序來處理定時器事件。當處理器正忙于其它事件處理時,定時器就不能立即處理。
QObject類還提供定時期的功能。與定時器相關的成員函數(shù)有:startTimer()、timeEvent()、killTimer()。QObject基類中的startTimer()和timerEvent()原型及說明如下:
intQObject::startTimer(int interval);
開始一個定時器并返回定時器ID,如果不能開始一個定時器,將返回0。定時器開始后,每隔interval毫秒間隔將觸發(fā)一次超時事件,直到killTimer()被調用來刪除定時器。如果interval為0,那么定時器事件每次發(fā)生時沒有窗口系統(tǒng)事件處理。
virtual voidQObject::timerEvent(QTimerEvent *event);
虛函數(shù)timerEvent()被重載來實現(xiàn)用戶的超時事件處理函數(shù)。如果有多個定時器在運行,QTimerEvent::timerId()被用來查找指定定時器,對其進行操作。
當定時器事件發(fā)生時,虛函數(shù)timerEvent()隨著QTimerEvent事件參數(shù)類一起被調用,重載這個函數(shù)可以獲得定時器事件。
定時器的用法如下:
//頭文件
class QNewObject : publicQObject
{
Q_OBJECT
public:
QNewObject( QObject * parent = 0 );
virtual ~QNewObject();
protected:
void timerEvent( QTimerEvent *event );
int m_nTimerId;
};
//源文件
QNewObject::QNewObject(QObject * parent )
:QNewObject( parent )
{
m_nTimerId = startTimer(1000);
}
QNewObject::~QNewObject()
{
if ( m_nTimerId != 0 )
killTimer(m_nTimerId);
}
voidQNewObject::timerEvent( QTimerEvent *event )
{
qDebug( "timer event, id %d",event->timerId() );
}
2.定時器類QTimer
定時器類QTimer提供當定時器觸發(fā)的時候發(fā)射一個信號的定時器,他提供只觸發(fā)一次的超時事件,通常的使用方法如下:
//創(chuàng)建定時器
QTimer *testTimer = newQTimer(this);
//將定時器超時信號與槽(功能函數(shù))聯(lián)系起來
connect( testTimer,SIGNAL(timeout()), this, SLOT(testFunction()) );
//開始運行定時器,定時時間間隔為1000ms
testTimer->start(1000);
...
//停止運行定時器
if (testTimer->isActive() )
testTimer->stop();
QTimer還提供了一個簡單的只有一次定時的函數(shù)singleShot()。 一個定時器在100ms后觸發(fā)處理函數(shù)animateTimeout()并且只觸發(fā)一次。代碼如下:
QTimer::singleShot( 100,this, SLOT(animateTimeout()) );
QTimer類提供了定時器信號和單觸發(fā)定時器。
它在內(nèi)部使用定時器事件來提供更通用的定時器。QTimer很容易使用:創(chuàng)建一個QTimer,使用start()來開始并且把它的timeout()連接到適當?shù)牟邸.斶@段時間過去了,它將會發(fā)射timeout()信號。
注意當QTimer的父對象被銷毀時,它也會被自動銷毀。
實例:
QTimer *timer = new QTimer( myObject );
connect( timer, SIGNAL(timeout()),myObject, SLOT(timerDone()) );
timer->start( 2000, TRUE ); // 2秒單觸發(fā)定時器
你也可以使用靜態(tài)的singleShot()函數(shù)來創(chuàng)建單觸發(fā)定時器。
作為一個特殊情況,一旦窗口系統(tǒng)事件隊列中的所有事件都已經(jīng)被處理完,一個定時為0的QTimer就會到時間了。
這也可以用來當提供迅速的用戶界面時來做比較繁重的工作。
QTimer *t = new QTimer( myObject );
connect( t, SIGNAL(timeout()), SLOT(processOneThing()));
t->start( 0, FALSE );
myObject->processOneThing()將會被重復調用并且應該很快返回(通常在處理一個數(shù)據(jù)項之后),這樣Qt可以把事件傳送給窗口部件并且一旦它完成這個工作就停止這個定時器。這是在圖形用戶界面應用程序中實現(xiàn)繁重的工作的一個典型方法,現(xiàn)在多線程可以在越來越多的平臺上使用,并且我們希望無效事件最終被線程替代。
注意QTimer的精確度依賴于底下的操作系統(tǒng)和硬件。絕大多數(shù)平臺支持20毫秒的精確度,一些平臺可以提供更高的。如果Qt不能傳送定時器觸發(fā)所要求的數(shù)量,它將會默默地拋棄一些。
另一個使用QTimer的方法是為你的對象調用QObject::startTimer()和在你的類中(當然必須繼承QObject)重新實現(xiàn)QObject::timerEvent()事件處理器。缺點是timerEvent()不支持像單觸發(fā)定時器或信號那樣的高級水平。
一些操作系統(tǒng)限制可能用到的定時器的數(shù)量,Qt會盡力在限制范圍內(nèi)工作。