Qt程序執行QApplication::exec()函數后,將進入事件循環來監聽應用程序的事件,Qt中所有的事件類都繼承於QEvent。
事件發生時,Qt創建一個事件對象,傳遞給QObject的event()函數,event()函數並不直接處理事件,而是對這些事件按照它們不同的類型分發給不同的事件處理函數。
event()函數主要用於事件的分發,如果要在事件分發之前做一些操作,就需要重寫event()函數。
鼠標事件:
#include <QMouseEvent>
1 void mousePressEvent(QMouseEvent *event); //單擊 2 void mouseReleaseEvent(QMouseEvent *event); //釋放 3 void mouseDoubleClickEvent(QMouseEvent *event); //雙擊 4 void mouseMoveEvent(QMouseEvent *event); //移動 5 void wheelEvent(QWheelEvent *event); //滾輪
1 void QtEventTest::mousePressEvent(QMouseEvent *event) 2 { 3 if (event->button() == Qt::LeftButton) 4 { 5 6 } 7 else if (event->button() == Qt::RightButton) 8 { 9 10 } 11 } 12 13 void QtEventTest::mouseReleaseEvent(QMouseEvent *event) 14 { 15 16 } 17 18 void QtEventTest::mouseDoubleClickEvent(QMouseEvent *event) 19 { 20 if (event->button() == Qt::LeftButton) 21 { 22 } 23 else if (event->button() == Qt::RightButton) 24 { 25 } 26 } 27 28 void QtEventTest::mouseMoveEvent(QMouseEvent *event) //默認情況下,此觸發事件需要點擊一下,才能觸發。可設置為自動觸發:setMouseTracking(true); 29 { 30 if (event->buttons() & Qt::LeftButton) //buttons() 位與 左擊 31 { 32 } 33 } 34 35 void QtEventTest::wheelEvent(QWheelEvent *event) 36 { 37 if (event->delta() > 0) 38 { 39 //遠離使用者方向滾動 40 } 41 else 42 { 43 //靠近使用者方向滾動 44 } 45 }
Qt中buttons()和button()的區別,官方解析如下:
Qt::MouseButton QMouseEvent::button() const
返回產生事件的按鈕
Qt::MouseButton QMouseEvent::buttons() const
返回產生事件的按鈕狀態,函數返回當前按下的所有按鈕,按鈕狀態可以是Qt::LeftButton,Qt::RightButton,Qt::MidButton或運算組合
假設鼠標左鍵已經按下,
如果移動鼠標,會發生的move事件,button返回Qt::NoButton,buttons返回LeftButton。
再按下了右鍵,會發生press事件,button返回RightButton,buttons返回LeftButton | RightButton
再移動鼠標,會發生move事件,button返回Qt::NoButton,buttons返回LeftButton | RightButton
再松開左鍵,會發生Release事件,button返回LeftButton,buttons返回RightButton
也就是說,button返回“那個按鈕發生了此事件”,buttons返回"發生事件時哪些按鈕還處於按下狀態"
鍵盤事件:
#include <QKeyEvent>
1 void keyPressEvent(QKeyEvent *event); //按下 2 void keyReleaseEvent(QKeyEvent *event); //釋放
從網上查資料發現,Qt的按鍵消息響應keyPressEvent()表現為按住一個鍵時,會先響應一次,停頓一會,然后開始不斷響應。
而且Qt的鍵盤函數有一個問題,它不是“按下按鍵才觸發keyPressEvent(), 彈起按鍵才觸發keyReleaseEvent()",而是”輸出按鍵消息前觸發keyPressEvent(),輸出后觸發keyReleaseEvent()“,表現為按住一個鍵時,不斷地press、release、press、release、press、release......
Qt的QKeyEvent類中提供isAutoRepeat()判斷,即按住按鍵時觸發的那些鍵盤事件isAutoRepeat類型,可以據此排除中間觸發的那些press和release
綜上所述,Qt的鍵盤事件整體表現為,按住一個鍵時:
1、第一次觸發keyPressEvent(), isAutoRepeat()返回false
2、沒有觸發keyReleaseEvent(),停頓一會
3、再一次觸發keyPressEvent(),isAutoRepeat()返回true
4、觸發keyReleaseEvent()
5、若沒松開按鍵,isAutoRepeat()返回true,返回第3步;若松開按鍵,isAutoRepeat()返回false
1 void QtEventTest::keyPressEvent(QKeyEvent *event) 2 { 3 if (event->key() == Qt::Key_Up) 4 { 5 //避免自動重復,按鍵重復時return; 6 if (event->isAutoRepeat()) 7 { 8 return; 9 } 10 11 ... 12 keyUp = true; //標記向上方向鍵已經按下 13 } 14 else if (event->key() == Qt::Key_Left) 15 { 16 if (event->isAutoRepeat()) 17 { 18 return; 19 } 20 21 ... 22 keyLeft = true; 23 } 24 } 25 26 void QtEventTest::keyReleaseEvent(QKeyEvent *event) 27 { 28 if (event->key() == Qt::Key_Up) 29 { 30 if (event->isAutoRepeat()) 31 { 32 return; 33 } 34 35 ... 36 } 37 else if (event->key() == Qt::Key_Left) 38 { 39 if (event->isAutoRepeat()) 40 { 41 return; 42 } 43 44 ... 45 } 46 }
