1. 程式人生 > >Qt中兩種定時器用法

Qt中兩種定時器用法

在Qt中使用定時器有兩種方法,一種是使用QObiect類的定時器;一種是使用QTimer類。定時器的精確性依賴於作業系統和硬體,大多數平臺支援20ms的精確度。

1.QObject類的定時器

    QObject是所有Qt物件的基類,它提供了一個基本的定時器。通過QObject::startTimer(),可以把一個一毫秒為單位的時間間隔作為引數來開始定時器,這個函式返回一個唯一的整數定時器的識別符號。這個定時器開始就會在每一個時間間隔"觸發",直到明確的使用這個定時器的識別符號來呼叫QObject::killTimer()結束。

    當定時器觸發時,應用程式會發送一個QTimerEvent。在事件迴圈中,處理器按照事件佇列的順序來處理定時器事件。當處理器正忙於其它事件處理時,定時器就不能立即處理。

    QObject類還提供定時期的功能。與定時器相關的成員函式有:startTimer()、timeEvent()、killTimer()。QObject基類中的startTimer()和timerEvent()原型及說明如下:

intQObject::startTimer(int interval);

    開始一個定時器並返回定時器ID,如果不能開始一個定時器,將返回0。定時器開始後,每隔interval毫秒間隔將觸發一次超時事件,直到killTimer()被呼叫來刪除定時器。如果interval為0,那麼定時器事件每次發生時沒有視窗系統事件處理。

virtual voidQObject::timerEvent(QTimerEvent *event);

    虛擬函式timerEvent()被過載來實現使用者的超時事件處理函式。如果有多個定時器在執行,QTimerEvent::timerId()被用來查詢指定定時器,對其進行操作。

    當定時器事件發生時,虛擬函式timerEvent()隨著QTimerEvent事件引數類一起被呼叫,過載這個函式可以獲得定時器事件。

    定時器的用法如下:

//標頭檔案

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提供當定時器觸發的時候發射一個訊號的定時器,他提供只觸發一次的超時事件,通常的使用方法如下:

//建立定時器

QTimer *testTimer = newQTimer(this);

//將定時器超時訊號與槽(功能函式)聯絡起來

connect( testTimer,SIGNAL(timeout()), this, SLOT(testFunction()) );

//開始執行定時器,定時時間間隔為1000ms

testTimer->start(1000);

...

//停止執行定時器

if (testTimer->isActive() )

    testTimer->stop();

  QTimer還提供了一個簡單的只有一次定時的函式singleShot()。 一個定時器在100ms後觸發處理函式animateTimeout()並且只觸發一次。程式碼如下:

QTimer::singleShot( 100,this, SLOT(animateTimeout()) );

QTimer類提供了定時器訊號和單觸發定時器。

它在內部使用定時器事件來提供更通用的定時器。QTimer很容易使用:建立一個QTimer,使用start()來開始並且把它的timeout()連線到適當的槽。當這段時間過去了,它將會發射timeout()訊號。

注意當QTimer的父物件被銷燬時,它也會被自動銷燬。

例項:

        QTimer *timer = new QTimer( myObject );

        connect( timer, SIGNAL(timeout()),myObject, SLOT(timerDone()) );

        timer->start( 2000, TRUE ); // 2秒單觸發定時器

你也可以使用靜態的singleShot()函式來建立單觸發定時器。

作為一個特殊情況,一旦視窗系統事件佇列中的所有事件都已經被處理完,一個定時為0的QTimer就會到時間了。

這也可以用來當提供迅速的使用者介面時來做比較繁重的工作。

        QTimer *t = new QTimer( myObject );

        connect( t, SIGNAL(timeout()), SLOT(processOneThing()));

        t->start( 0, FALSE );

myObject->processOneThing()將會被重複呼叫並且應該很快返回(通常在處理一個數據項之後),這樣Qt可以把事件傳送給視窗部件並且一旦它完成這個工作就停止這個定時器。這是在圖形使用者介面應用程式中實現繁重的工作的一個典型方法,現在多執行緒可以在越來越多的平臺上使用,並且我們希望無效事件最終被執行緒替代。

注意QTimer的精確度依賴於底下的作業系統和硬體。絕大多數平臺支援20毫秒的精確度,一些平臺可以提供更高的。如果Qt不能傳送定時器觸發所要求的數量,它將會默默地拋棄一些。

另一個使用QTimer的方法是為你的物件呼叫QObject::startTimer()和在你的類中(當然必須繼承QObject)重新實現QObject::timerEvent()事件處理器。缺點是timerEvent()不支援像單觸發定時器或訊號那樣的高階水平。

一些作業系統限制可能用到的定時器的數量,Qt會盡力在限制範圍內工作。