Qt事件循環


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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM