- 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:
- QEvent是Qt中所有事件的基礎類別,最常見的事件類型皆為其子類別,像是滑鼠事件的QMouseEvent、鍵盤事件的QKeyEvent、縮放事件的QResizeEvent等,這些子類別事件皆加入其特定的函式。
- 滑鼠事件的x()、y():指出發生滑鼠事件時,滑鼠游標的x、y座標。
- 鍵盤事件的key():可以取得目前所按下的按鍵常數。
- 以圖形元件來說,通常會繼承QWidget或其子類別,並重新定義事件處理者,也就是事件處理函式,QWidget定義了:keyPressEvent()、keyReleaseEvent()、mouseDoubleClickEvent()、mouseMoveEvent()、mousePressEvent()、mouseReleaseEvent()等事件處理函式,並接受QEvent的特定子類別實例作為引數,只要根據想要處理的事件重新定義對應的函式即可進行事件處理。
Qt的事件跟Signal、Slot機制是不同的。Signal與Slot的機制是同步的(Synchronous),Signal是由物件發出的,使用QObject的connect()連接物件上定義的Slot來立即處理。
Qt的事件可以是非同步的(Asynchronous)的,Qt使用一個事件佇列來維護,新的事件產生時基本上會被排到佇列的尾端,前一個事件處理完成,再從佇列的前端取出下一個佇列來處理,必要的時候,Qt的事件也可以是同步的,而事件還可以使用事件過濾器 進行過濾處理。
本文參考自"良葛格:Qt4學習筆記"
0 意見:
張貼留言