日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Qt学习笔记之事件处理

發布時間:2024/9/21 编程问答 58 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Qt学习笔记之事件处理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1. Qt事件概述

事件是對各種應用程序需要知道的由應用程序內部或者外部產生的事情或者動作的通稱。對于初學者,總會對Qt中信號和事件的概念混淆不清。其實,記住事件比信號更底層就可以了。比如說,我們用鼠標按下界面上的一個按鈕,它會發射clicked()單擊信號,但是,它怎么知道自己被按下的呢,那就是通過鼠標事件處理的。這里可以看到,鼠標事件比信號更底層。

在Qt中處理事件有多種方法,不過最常用的是重寫Qt事件處理函數。

2. Qt事件的來源

?

?

3. Qt事件機制

Qt中定義的事件是一個從QEvent類繼承而來的對象,它表示應用程序內部或外部發生了某些應用程序自身必須知道的事情。任何從QObject類派生的對象均可以通過QObject::event()方法接收事件。事件產生時,Qt會創建一個合適的QEvent對象或其子對象,然后通過調用QObject類的event()函數將這個事件對象傳給特定的QObject對象或其子對象。需要指出的是,event()函數自身并不處理事件,而是根據事件類型調用相應的事件處理器,其返回值告知這個事件是否被接受并進行了處理。例如,QWidget類中的event()函數實現將鼠標、鍵盤和重繪等常見事件交給mousePressEvent()、keyPressEvent()和paintEvent()這些特定的事件處理器進行處理。

事件處理方式順序:

  • Qt事件產生后立即被分發到QWidget對象
  • QWidget中的event(QEvent*)進行事件處理
  • event()根據事件類型調用不同的事件處理函數
  • 在事件處理函數中發送Qt中預定義的信號
  • 調用信號關聯的槽函數

在Qt內部,Qt通過由函數QCoreApplication::exec()啟動的主事件循環不停抓取事件隊列中的本地窗口事件,然后將它們轉換成對應的QEvent對象,并最終將這些QEvent對象發送到目的QObject對象來完成上述一系列事件的處理動作。

需要注意的是,不應該混淆事件和信號這兩個概念。通常,在使用已有的窗口部件時,信號是十分有用的,而在自定義新的窗口部件時,事件則更為重要。舉例來講,當使用QPushButton類時,程序員往往只關注其clicked()信號,而很少關心底層的鼠標或者鍵盤事件。但當自定義一個類似QPushButton的類時,程序員就不得不編寫一定量的代碼來處理鼠標或者鍵盤事件,并在適當的時候發送clicked()信號。從這個角度講,事件比信號更底層

Qt的事件處理有5種級別:

1.??????重寫控件的事件處理函數:如重寫keyPressEvent(),mousePressEvent()和paintEvent(),這是最常用的事件處理方法,我們已經看到過很多這樣的例子了。

2.??????重寫QObject::event(),在事件到達事件處理函數前處理它。在需要改變Tab鍵的慣用法時這樣做。也可以處理那些沒有特定事件處理函數的比較少見的事件類型(例如,QEvent::HoverEnter)。我們重寫event()時,必須要調用基類的event(),由基類處理我們不需要處理的那些情況。

3.??????給單獨的QObject對象安裝事件過濾器:對象用installEventFilter()注冊后,所有目標對象的事件都首先到達監視對象的eventFilter()函數。如果一個對象有多個事件過濾器,過濾器按順序激活,先到達最近安裝的監視對象,最后到達最先安裝的監視對象。

4.??????給QApplication對象安裝事件過濾器,如果qApp(唯一的QApplication對象)安裝了事件過濾器,程序中所有對象的每個事件在被送到任何其它事件過濾器之前都要送到eventFilter()函數中。這個方法在調試的時候非常有用,在處理禁止使能狀態的控件的鼠標事件時這個方法也很常用。

5.??????繼承QApplication,重寫notify()。Qt調用QApplication::nofity()來發送事件。重寫這個函數是在其他事件過濾器接收事件前得到所有事件的唯一方法。通常事件過濾器是最有用的,因為在同一時間,可以有任意數量的事件過濾器,但是notify()函數只有一個。

4.? 鼠標事件

QKeyEvent類:描述一個鍵盤事件。當鍵盤按鍵被按下或者被釋放時,鍵盤事件便會被發送給擁有鍵盤輸入焦點的部件。

相關函數:

key(); //獲取鍵盤對應的鍵值,不區分大小寫 void keyPressEvent(QKeyEvent *event);? ? //按下事件 void keyReleaseEvent(QKeyEvent *event); //抬起事件

單個事件:

if (event->key() == Qt::Key_Up){ }

組合事件:

if (event->modifiers() == Qt::ControlModifier){ }

void Widget::keyPressEvent(QKeyEvent *event) {int x,y;if (event->modifiers() == Qt::ControlModifier) {switch (event->key()) {case Qt::Key_Down:x = m_endPt.x()+10;y = m_endPt.y()+10;m_endPt.setX(x);m_endPt.setY(y);update();m_bIsDrawing = true;break;case Qt::Key_Up:x = m_endPt.x()-10;y = m_endPt.y()-10;m_endPt.setX(x);m_endPt.setY(y);update();m_bIsDrawing = true;break;}} }void Widget::keyReleaseEvent(QKeyEvent *event) {switch (event->key()) {case Qt::Key_Down:m_bIsDrawing = false;update();break;case Qt::Key_Up:m_bIsDrawing = false;update();break;} }

5.? 鍵盤事件

QMouseEvent類:表示一個鼠標事件,當在窗口部件中按下抬起鼠標或者移動鼠標指針時,都會產生鼠標事件。

相關函數:

button(); //返回鼠標的事件值 buttons(); //返回鼠標的事件值(移動事件時) x(); //返回X坐標 y(); //返回Y坐標 pos(); //返回X和Y坐標 void mousePressEvent(QMouseEvent *event); //按下事件處理函數 void mouseReleaseEvent(QMouseEvent *event); //彈起事件處理函數 void mouseDoubleClickEvent(QMouseEvent *event);//雙擊事件處理函數 void mouseMoveEvent(QMouseEvent *event); //移動事件處理函數

?鼠標事件值:

QWheelEvent類:表示鼠標滾輪事件,在這個類中主要是獲取滾輪移動方向和距離

相關函數 :

delta() //獲取滾輪移動的距離函數 每當滾輪旋轉一下,默認的是15度向上滾動,delta()函數返回正值向下滾動,delta()函數返回負值 void wheelEvent(QWheelEvent *event); void Widget::mousePressEvent(QMouseEvent *event) {if (event->button() == Qt::LeftButton){m_lastPt = event->pos();m_bIsDrawing = true; //正在繪圖} }void Widget::mouseReleaseEvent(QMouseEvent *event) {if (event->button() == Qt::LeftButton){m_endPt = event->pos();m_bIsDrawing = false;update();}}void Widget::mouseMoveEvent(QMouseEvent *event) {if (event->buttons() == Qt::LeftButton){m_endPt = event->pos();update();}}

6. 定時器事件

Qt中有兩種方法來使用定時器,一種是定時器事件,另一種是使用信號和槽。一般使用了多個定時器時最好使用定時器事件來處理。

6.1 多個定時器

QTimerEvent類:定時器事件類。

相關函數:

timerId(); // 返回定時器值 void timerEvent(QTimerEvent *event); // 定時器事件處理函數 m_timerId1 = startTimer(1000);m_timerId2 = startTimer(1000);m_timerId3 = startTimer(1000);

這里開啟了三個定時器,分別返回了它們的id,這個id用來區分不同的定時器。定時器的時間單位是毫秒。每當一個定時器溢出時,都會調用定時器事件處理函數,我們可以在該函數中進行相應的處理。

void Widget::timerEvent(QTimerEvent *event) {if (event->timerId() == m_timerId1) {qDebug("style 2:timerId %d,hello world...",event->timerId());}else if (event->timerId() == m_timerId2){qDebug("style 2:timerId %d,hello world...",event->timerId());}else if (event->timerId() == m_timerId3){qDebug("style 2:timerId %d,hello world...",event->timerId());} }

6.2 信號與槽方式

如果只是想開啟少量的定時器,也可以使用信號和槽來實現。?

QTimer *timer = new QTimer(this);connect(timer,SIGNAL(timeout()),this,SLOT(updateTimer()));timer->start(1000); void Widget::updateTimer() {qDebug("style 1: hello world ....."); }

?

7.?事件過濾

相關函數:

bool eventFilter(QObject *watched, QEvent *event); // 過濾器函數 參數:1.接受事件的對象 2.事件類型 void installEventFilter(QObject *filterObj); // 安裝一個過濾器 bool myApplication::eventFilter(QObject *obj, QEvent *event) {static int k=1;if(event->type()==QEvent::MouseButtonPress||event->type()==QEvent::MouseButtonDblClick){qDebug()<<"Click"<<k;k++;return true;}return QApplication::eventFilter(obj,event);}

?

?

參考資料:

1.?Qt5 事件(event)機制詳解

2.?17.QT-事件處理分析、事件過濾器、拖放事件

3.?QT基礎:66---事件處理(鍵盤事件、鼠標事件、滾輪事件、事件過濾器)

4.?Qt之事件處理機制

5.?Qt事件原理

總結

以上是生活随笔為你收集整理的Qt学习笔记之事件处理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。