成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

詳解 QT Event 以及 Event Filter 事件處理

移動(dòng)開發(fā)
本文介紹的是詳解 QT Event 以及 Event Filter 事件處理,不多說,先來看內(nèi)容,更多相關(guān)內(nèi)容參考文章末尾。

QT Event 以及 Event Filter 事件處理是本文要介紹的內(nèi)容,詳細(xì)內(nèi)容如下,先來看內(nèi)容。Event 和 Event Filters:

1、手動(dòng)發(fā)送事件流程:

(1)構(gòu)造自己的事件對象:

  1. QEvent *evt = new QEvent( QEvent::Close  );  

(2)發(fā)送給指定的對象:

  1. QApplication::sendEvent(this, evt );  

2、定制某個(gè)控件的事件處理:

(1)確定需要對哪些控件的哪些事件, 通常的 close以及 key 和 keyboard 事件;

(2)重寫該對象的 event() 函數(shù);
      
3、事件過濾流程: 
 
(1)確定自己需要過濾處理哪些對象的那些事件;   
    
(2)構(gòu)造自己的事件過濾類: 重寫該類的 eventFilter 函數(shù);

(3)在主程序中實(shí)例化一個(gè)過濾類對象;
  
(4)調(diào)用該過濾類對象的 installEventFilter( receiver, QEvent *event),
  
以在目標(biāo)對象上安裝該過濾器。

在 Qt 中, event 被建模成派生自abstract QEvent 類的對象, 用來表示在應(yīng)用程序中發(fā)生的事件,或是應(yīng)用程序需要處理的外部活動(dòng)產(chǎn)生的事件.

Events 可以被任一 QObject 派生的子類實(shí)例對象接收和處理, 但他們是關(guān)聯(lián)到特定控件的. 本文檔描述 event 在典型應(yīng)用程序中是如何發(fā)送及處理的.

  1. How Events are Delivered   
  2. Event Types   
  3. Event Handlers   
  4. Event Filters   
  5. Sending Events 

 

event 如何發(fā)送

通常情況下,當(dāng)一個(gè)事件發(fā)生的時(shí)候, Qt 通過構(gòu)造一個(gè)合適的 QEvent子類對象來表示事件的發(fā)生, 然后將該事件對象發(fā)送給特定的 QObject對象( 或其子類實(shí)例對象), 通過調(diào)用該 QObject 的 event() 函數(shù). 這個(gè) event() 函數(shù)不會(huì)對事件本身進(jìn)行處理, 而是首先檢查所接受到event 的類型, 然后根據(jù) event 的類型來調(diào)用相應(yīng)的 event handler, event handler 在處理完 event 之后會(huì)返回一個(gè)bool值表示 該 event是被接受了,還是被忽略了。

某些事件, 例如 QMouseEvent 和 QKeyEvent, 來自于窗口系統(tǒng); 某些, 例如 QTimerEvent, 來自于其他的事件源; 某些, 來自于應(yīng)用程序本身.

Event 類型

Qt為多數(shù) Event 類型建立了相應(yīng)的類, 常見有QResizeEvent, QPaintEvent, QMouseEvent, QKeyEvent, QCloseEvent.

每一個(gè)特定的 event 類都是繼承自 QEvent 基類,添加特定的事件函數(shù). 例如, QResizeEvent 添加了 size() 和 oldSize() 讓控件可以發(fā)現(xiàn)他們的尺度,發(fā)生了的怎么改變.

某些類實(shí)際支持不止一種事件類型. QMouseEvent 就支持鼠標(biāo)按鍵按下事件,雙擊事件, 移動(dòng)事件, 以及其他相關(guān)操作所引發(fā)的事件.

每一個(gè)事件都有它的類型, 由 QEvent::Type 定義, 運(yùn)行時(shí)可以很方便的檢測每個(gè)事件對象的事件類型,以快速的判斷該事件對象構(gòu)造自哪個(gè)事件類.

由于程序需要和又多樣又復(fù)雜的事件進(jìn)行交互, 所以 Qt 的 event 發(fā)送機(jī)制設(shè)計(jì)非常有彈性.

QCoreApplication::notify() 的文檔簡潔的說明了整個(gè)機(jī)制:

  1. bool QCoreApplication::notify ( QObject * receiver, QEvent * event )   [virtual]  

發(fā)送 event 給 接收者: receiver->event(event). 返回從 receiver 的 event handler 返回的值. 注意這個(gè)函數(shù)適用于該應(yīng)用程序中的任何線程中的任何對象. 對于特定類型的事件 (例如, 鼠標(biāo)和鍵盤事件), 該事件將被傳送到 receiver 的 parent 并這樣逐級上傳

直到傳到 top-level object, 如果這些 receiver 都沒有對該事件進(jìn)行處理的話(比如, 它返回 false ).

共五種處理 event 的方法; 重寫(重實(shí)現(xiàn)) QCoreApplication::notify() 這個(gè) virtual 函數(shù)只是其 中的一種. 以下列出了這五種方法:

1、重寫 paintEvent(), mousePressEvent() 等. 這是最常用, 最簡單但也是最有限的方式.

2、重寫 QCoreApplication::notify(). 這非常強(qiáng)大, 可以完全控制事件處理; 但一次只可用于一個(gè)子類.

3、給 QCoreApplication::instance() 安裝一個(gè) event filter .這個(gè) event filter 就能處理所有控件的所有事件, 因此這與重寫 notify() 一樣強(qiáng)大; 此外, 可以有不止一個(gè)應(yīng)用程序全局級的 event filter. 應(yīng)用程序全局級 event filter 甚至可以收到已禁用控件的鼠標(biāo)事件.

注意:  應(yīng)用程序級 event filter 僅能用于存活在主線程中的對象.

4、 重寫 QObject::event()( 像 QWidget 那樣 ). 如果你重寫了 QObject::event(), 當(dāng) Tab 鍵按下時(shí), 你就可以在任何控件級 event filter 捕獲這個(gè) Tab 鍵按下事件之前處理這個(gè)事件.

5、給相應(yīng)的接收對象安裝一個(gè) event filter. 例如一個(gè)捕獲所有事件的 event filter, 包含 Tab 和Shift+Tab 鍵按下事件, 在它們沒有改變焦點(diǎn)控件之前.

另請參考 QObject::event() 以及 installEventFilter().

Event Handlers

處理 event 的標(biāo)準(zhǔn)方式是調(diào)用一個(gè) virtual 函數(shù). 例如, QPaintEvent 是通過調(diào)用 QWidget::paintEvent() 來處理的. 這個(gè) virtual 函數(shù)負(fù)責(zé)進(jìn)行相應(yīng)的處理, 通常就是重畫該控件. 如果你在自己實(shí)現(xiàn)的 virtual 函數(shù)中沒有做所有必要的工作, 你就有必要調(diào)用它的基類實(shí)現(xiàn).

例如, 下面的代碼處理一個(gè)定制 checkbox 控件的鼠標(biāo)左鍵點(diǎn)擊事件, 并將所有其他點(diǎn)擊事件轉(zhuǎn)發(fā)給它的基類 QCheckBox 類:

  1. void MyCheckBox::mousePressEvent(QMouseEvent *event)   
  2. {   
  3.     if (event->button() == Qt::LeftButton) {   
  4.         // handle left mouse button here   
  5.     } else {   
  6.         // pass on other buttons to base class   
  7.         QCheckBox::mousePressEvent(event);   
  8.     }   
  9. }  

如果你需要替換基類的函數(shù), 你應(yīng)該自己實(shí)現(xiàn)所有相關(guān)的處理. 但是, 如果你只想擴(kuò)展基類的功能, 那么你就只需實(shí)現(xiàn)需要實(shí)現(xiàn)的部分, 然后調(diào)用基類處理函數(shù)來處理你不想處理的情況.

偶爾, 你要處理沒有相應(yīng)處理函數(shù)的特定事件, 或遇到事件處理函數(shù)不夠用情況. 最常見的例子是 Tab 鍵按下事件. 通常, QWidget 截獲到 Tab 鍵按下事件后,會(huì)移動(dòng)鍵盤焦點(diǎn), 但是少數(shù)控件需要自己來處理這個(gè)事件. 這些對想可以重寫 QObject::event() 函數(shù), 通用的 event handler, 然后在通常處理過程之前或之后寫自己的事件處理過程, 或完全替代原處理過程. 下面是這樣一個(gè)很常見的控件:

一個(gè)既自己處理 Tab 事件又自己處理某些按鍵事件, 然后將其它不需自己處理的事件轉(zhuǎn)發(fā)給基類處理:

  1. bool MyWidget::event(QEvent *event)   
  2. {   
  3.     if (event->type() == QEvent::KeyPress) {   
  4.         QKeyEvent *ke = static_cast<QKeyEvent *>(event);   
  5.         if (ke->key() == Qt::Key_Tab) {   
  6.             // special tab handling here   
  7.             return true;   
  8.         }   
  9.     } else if (event->type() == MyCustomEventType) {   
  10.         MyCustomEvent *myEvent = static_cast<MyCustomEvent *>(event);   
  11.         // custom event handling here   
  12.         return true;   
  13.     }   
  14.  
  15.     return QWidget::event(event);   
  16. }  

值得注意的是對沒有處理的事件仍調(diào)用 QWidget::event(), 并返回該基類調(diào)用的返回值以指示事件是否被處理了; 若返回 true 值則將會(huì)禁止將該事件再發(fā)往其他對象.

Event Filters

有時(shí)候一個(gè)對象需要檢查, 還可能截取發(fā)往其它對象的事件.例如, 對話框通常需要過濾發(fā)往某些控件的事件, 比如 更改 Enter 鍵按下的事件處理.

通過調(diào)用過濾器對象的 QObject::installEventFilter() 函數(shù), 為目標(biāo)對象設(shè)置一個(gè) event filter, 就可在過濾器對象的QObject::eventFilter() 函數(shù)中處理發(fā)往目標(biāo)對象的事件. 一個(gè) event filter 在目標(biāo)對象收到事件之前處理事件, 這使得過濾器對象在需要的時(shí)候可以檢查并丟棄事件. 一個(gè)現(xiàn)有的 event filter 可以調(diào)用 QObject::removeEventFilter() 來移除已經(jīng)安裝的 event filter .

當(dāng)過濾器的 eventFilter() 實(shí)現(xiàn)被調(diào)用的時(shí)候, 它就可以選擇是處理該事件,還是轉(zhuǎn)發(fā)該事件, 或禁止該事件繼續(xù)被其它對象處理. 若所有的事件過濾器都允許一個(gè)事件可被繼續(xù)處理( 每個(gè)過濾器處理后都返回 false ), 該事件最終將被發(fā)送到目標(biāo)對象. 如果其中一個(gè)中止了這個(gè)流程(通過返回 TRUE),

則后面的過濾器對象以及目標(biāo)對象將不會(huì)收到該事件.

  1. bool FilterObject::eventFilter(QObject *object, QEvent *event)   
  2. {   
  3.     if (object == target && event->type() == QEvent::KeyPress) {   
  4.         QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);   
  5.         if (keyEvent->key() == Qt::Key_Tab) {   
  6.             // Special tab handling   
  7.             return true;   
  8.         } else   
  9.             return false;   
  10.     }   
  11.     return false;   
  12. }  

上面代碼演示了另外一種截取發(fā)往特定對象 Tab 鍵事件的方法. 在這個(gè)例子里, 該過濾器處理 Tab 事件后返回 true 來阻止它們被繼續(xù)處理. 所有其他的按鍵事件將被忽略掉,然后過濾器返回 false 來允許該事件被已安裝的后續(xù)過濾器處理, 最終發(fā)往目標(biāo)控件.

當(dāng)然也可以過濾整個(gè)應(yīng)用程序的所有事件, 只需將過濾器對象安裝到 QApplication 對象或QCoreApplication 對象上. 這樣的全局事件過濾器會(huì)在任何對象級過濾器()調(diào)用之前調(diào)用.

這是非常強(qiáng)大的, 但它也拖慢了整個(gè)應(yīng)用程序范圍內(nèi)每個(gè)事件的每次處理過程; 通常使用其他的技術(shù)來實(shí)現(xiàn)應(yīng)用程序全局的事件過濾.

發(fā)送事件

許多應(yīng)用程序需要?jiǎng)?chuàng)建并發(fā)送自己的事件. 你完全可以模仿 Qt 自有的 event loop 機(jī)制, 先構(gòu)造合適的事件對象, 然調(diào)用 QCoreApplication::sendEvent() QCoreApplication::postEvent() 來把這些構(gòu)造好的事件發(fā)送給指定的接收者.

sendEvent() 立即同步處理要發(fā)送的 event . 當(dāng)它返回的時(shí)候, 表示相關(guān)的事件過濾器 和/或目標(biāo)對象就處理完了該 event. 對于多數(shù)的 event 類, 有一個(gè)成員函數(shù) isAccepted() 可以用來判別該事件是已被接受處理了,還是被拒絕處理了.

postEvent() 將 event 提交到一個(gè)隊(duì)列中等待調(diào)度. 在下一次 Qt 的主 event loop 運(yùn)行的時(shí)候,主 event loop 就會(huì)調(diào)度所有提交到隊(duì)列中的 event, 以某種優(yōu)化的方式. 例如, 如果有幾個(gè) resize event, 他們就會(huì)被壓縮成一個(gè)事件. 同樣適用于 paint events: QWidget::update() 調(diào)用postEvent(), 以避免多次重畫來避免閃爍以及提高速度.

postEvent() 也被用于對象的初始化過程, 因?yàn)樘峤贿^的 event 通常在相應(yīng)對象初始化完畢后極短的 時(shí)間內(nèi)就會(huì)被調(diào)度. 在實(shí)現(xiàn)一個(gè)控件的時(shí)候, 在自定義控件的 constructor 中盡早支持事件機(jī)制是非常重要的, 在可能接受到任何事件之前,確保盡早初始化成員變量.

要?jiǎng)?chuàng)建一個(gè)定制類型的 event, 你需要定義一個(gè)事件號( event number ), 這個(gè)事件號應(yīng)該大于QEvent::User, 并且你可能需要繼承 QEvent 以傳遞關(guān)于你定制的 event 類型的特定信息. 
參考 QEvent 文檔以獲取更多細(xì)節(jié).

小結(jié):關(guān)于詳解 QT Event 以及 Event Filter 事件處理的內(nèi)容介紹完了,希望本文對你有所幫助。更多請參考編輯推薦。

責(zé)任編輯:zhaolei 來源: 互聯(lián)網(wǎng)
相關(guān)推薦

2011-08-29 14:59:26

QtEvent事件

2023-02-19 12:44:07

領(lǐng)域事件DDD

2023-02-26 10:59:51

2010-10-09 10:30:03

JS event

2019-10-11 09:00:00

JavaScriptEvent Loop前端

2023-04-28 15:20:37

JavaScript事件循環(huán)

2022-04-13 11:02:12

鴻蒙事件模塊事件Event

2013-10-24 15:23:40

Event Loop

2021-06-04 09:57:49

鴻蒙HarmonyOS應(yīng)用

2022-11-10 15:19:24

JavaScript事件發(fā)射器通信

2023-11-22 12:42:19

CQRS事件溯源

2021-08-01 23:47:54

通用模型驅(qū)動(dòng)

2022-09-07 08:58:58

Node.js框架

2011-06-23 14:05:32

Qt 事件機(jī)制

2023-12-28 07:57:27

2022-02-10 16:11:26

EventMysql數(shù)據(jù)庫

2011-06-29 16:14:59

Qt 事件 過濾器

2023-09-27 08:01:14

數(shù)據(jù)推送事件

2011-07-01 14:20:59

Qt 事件

2011-07-01 14:14:34

Qt 事件
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 一区二区三区在线播放 | 国产麻豆乱码精品一区二区三区 | 麻豆一区一区三区四区 | 亚洲区一区二区 | 青青草国产在线观看 | 国产中文视频 | www.成人.com | 亚洲国产精品一区二区第一页 | 国产精品黄色 | 麻豆成人在线视频 | 日韩精品一区二区三区高清免费 | 精品日韩一区二区 | 欧美自拍另类 | 欧美一级艳情片免费观看 | 国产成人免费视频网站视频社区 | 亚洲精品区 | 亚洲一区二区三区观看 | 欧美日韩综合一区 | 国产成人99久久亚洲综合精品 | 日韩在线中文 | 国产在线观看 | 亚州中文字幕 | 91精品国产综合久久国产大片 | 成人在线免费观看 | 国产精品久久久久久久久久 | 五月综合激情网 | 亚州视频在线 | 国产一区二区免费 | 欧美日韩国产一区 | 中文字幕亚洲欧美日韩在线不卡 | 久久久精品综合 | 综合久久综合久久 | 91久色| 亚洲综合色 | www视频在线观看 | 久久久久久久久精 | 亚洲精品大全 | 日韩成人精品 | 在线欧美亚洲 | 做a网站| 夜夜爽99久久国产综合精品女不卡 |