天天看點

Qt中的消息通知和事件發送

Qt中的消息通知和事件發送

Qt中的信号和槽機制、事件機制是其具有特色的兩大機制。利用這兩種機制可以輕松地實作需要的消息通知和事件通知。

1、信号和槽機制

充分使用Qt庫中已經定義和實作好的對象的信号和槽函數,如按鈕的clicked()/pressed()信号等,它們能滿足很多的需求;

自定義缺乏的信号和槽函數,借助Qt的元對象系統和内省機制,在建立類時添加Q_OBJECT宏,使用signals:/slots:标記添加自定義的信号/槽函數,使用時通過emit發送信号,用connect()函數連接配接信号和槽。

2、事件機制

充分使用Qt庫中已經定義好的标準事件對象,如滑鼠事件QMouseEvent、鍵盤事件QKeyPressEvent等,自定義實作事件的處理函數,如keyPressEvent(QEvent*);

自定義需要的事件類型和實作QObject::customEvent(QEvent*)函數,使用Qt的postEvent和sendEvent函數發送事件通知。

(1)、自定義事件:

方式一;通過QEvent::Type指定事件類型的值,然後new一個該類型的自定義事件,如:

【QCustomEvent類是Qt3中的類,現在已經不推薦使用了。】

QEvent::Type是Qt中的枚舉類型,Qt定義了一大堆的庫事件類型常數值,當然也允許使用者自定義自己的事件類型值,但是自定義的值應大于1000(QEvent::User),且小于65535(QEvent::MaxUser).友善起見,可以使用int QEvent::registerEventType ( int hint = -1 ) [static]函數注冊和保留一個自定義的事件類型值,這樣可以避免不小心重複使用了同一個事件類型值,它保證每次得到一個未被使用的事件類型常數值,該函數是線程安全的,在Qt4.4中引入。

方式二:通過繼承QEvent建立新的事件類,如:

(2)、發送事件:postEvent/sendEvent/notify

postEvent函數:void QCoreApplication::postEvent ( QObject * receiver, QEvent * event ) [static]【異步】

将事件放入事件消息隊列中,然後立即傳回,函數隻将事件放入隊列的尾端,不保證事件立即得到處理。事件必須是配置設定在堆上的,即new出來的,因為在事件被發送出去後,事件隊列就擁有了事件的,事件處理完後Qt會自動delete該事件,是以在把事件posted出去後再嘗試使用它是不安全的。

當程式控制到達主事件循環時,事件隊列中的所有事件才用notify函數發送。事件的處理是按照其發送到隊列中的順序進行的,如果想要控制事件的優先級,可以考慮它的帶優先級參數的重載函數。

void QCoreApplication::postEvent ( QObject * receiver, QEvent * event, int priority ) [static]【Qt4.3引入】

這兩個函數都是線程安全的。

sendEvent函數:bool QCoreApplication::sendEvent ( QObject * receiver, QEvent * event ) [static]【同步】

用notify函數将事件直接派發給接收者和進行處理,傳回事件處理者的傳回值。事件會立即送至接受者,被發送後,Qt不會自動delete該事件,是以合适的做法是在棧上建立事件。

sendPostedEvents:

void QCoreApplication::sendPostedEvents ( QObject * receiver, int event_type ) [static]

将事件隊列中用postEvent函數放入的對應接受者和事件類型的事件立即分發,但是來自視窗系統的事件不被分發,它們被processEvents()函數分發。

如果接受者是null,則對應所有的接受者;如果event_type為0,則對應receiver的所有的事件。該函數必須和receiver在同一個線程内被調用。

void QCoreApplication::sendPostedEvents () [static]

分發事件隊列中的所有事件,即清空事件隊列。

notify:bool QCoreApplication::notify ( QObject * receiver, QEvent * event ) [virtual]

這是事件機制中最基本的函數,所有的事件發送最終都要調用這個函數。它把事件信号發送給接受者,并傳回receiver->event(event)處理的傳回值。

(3)、處理事件:void QObject::customEvent ( QEvent * event ) [virtual protected]

通過重載實作customEvent函數,可以對自定義的事件進行靈活的處理,如:

============= End