2010年9月13日 星期一

Qt4 學習筆記(五):Event Class & Event Handler

  • Event Class & Event Handler
    • 當執行QApplication的exec()方法之後,應用程式會進入事件迴圈來傾聽(Listen)應用程式的事件,事件來源通常是視窗系統,例如使用者的滑鼠事件或鍵盤事件,事件來源可以是Qt應用程式事件本身,例如QTimerEvent,事件來源也可以是使用者自定義的事件,透過QApplicaiton的sendEvent()或postEvent()來發送。
    • 當事件發生時,Qt為之建立事件實例,QEvent是Qt中所有事件的基礎類別,Qt所建立的事件實例為QEvent的子類別實例,並將之傳送給 QObject子類別實例的event()函式,event()這個函式本身通常不直接處理事件,而是基於所傳送的事件類型,分派給處理特定類型的事件處理者(Event Handler)。

以下是簡單的事件處理示範,繼承了QLabel並重新定義了相關的事件處理者,當滑鼠移動、按下或放開時,顯示滑鼠游標的所在位置。

#include <QApplication>
#include <QWidget>
#include <QLabel>
#include <QMouseEvent>

class EventLabel : public QLabel {
protected:
    void mouseMoveEvent(QMouseEvent *event);
    void mousePressEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);
};

void EventLabel::mouseMoveEvent(QMouseEvent *event) {
    QString msg;
    msg.sprintf("Move: (%d, %d)", event->x(), event->y());
    this->setText(msg);  
}

void EventLabel::mousePressEvent(QMouseEvent *event) {
    QString msg;
    msg.sprintf("Press: (%d, %d)", event->x(), event->y());
    this->setText(msg);
}

void EventLabel::mouseReleaseEvent(QMouseEvent *event) {
    QString msg;
    msg.sprintf("Release: (%d, %d)", event->x(), event->y());
    this->setText(msg);
}

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
 
    EventLabel *label = new EventLabel;
    label->setWindowTitle("MouseEvent Demo");
    label->resize(300, 200);
    label->show();
    
    return app.exec();
}

Notes:
  1. QEvent是Qt中所有事件的基礎類別,最常見的事件類型皆為其子類別,像是滑鼠事件的QMouseEvent、鍵盤事件的QKeyEvent、縮放事件的QResizeEvent等,這些子類別事件皆加入其特定的函式。
    • 滑鼠事件的x()、y():指出發生滑鼠事件時,滑鼠游標的x、y座標。
    • 鍵盤事件的key():可以取得目前所按下的按鍵常數。
  2. 以圖形元件來說,通常會繼承QWidget或其子類別,並重新定義事件處理者,也就是事件處理函式,QWidget定義了:keyPressEvent()、keyReleaseEvent()、mouseDoubleClickEvent()、mouseMoveEvent()、mousePressEvent()、mouseReleaseEvent()等事件處理函式,並接受QEvent的特定子類別實例作為引數,只要根據想要處理的事件重新定義對應的函式即可進行事件處理。
P.S.
Qt的事件跟Signal、Slot機制是不同的。Signal與Slot的機制是同步的(Synchronous),Signal是由物件發出的,使用QObject的connect()連接物件上定義的Slot來立即處理。

Qt的事件可以是非同步的(Asynchronous)的,Qt使用一個事件佇列來維護,新的事件產生時基本上會被排到佇列的尾端,前一個事件處理完成,再從佇列的前端取出下一個佇列來處理,必要的時候,Qt的事件也可以是同步的,而事件還可以使用事件過濾器 進行過濾處理。

本文參考自"良葛格:Qt4學習筆記"

0 意見: