国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

QT類 Qevent事件處理過程 事件過濾器

移動開發
本文介紹的是QT類 Qevent事件處理過程 事件過濾器,事件的操作應該友們很感興趣,先來看你本文介紹。

QT類 Qevent事件處理過程 事件過濾器 是本文要介紹的內容,我們直接進入內容。

事件處理流程:

某個事件發生------>exec()循環會接收到這個事件------>

創建一個事件對象,并將對象傳遞給QObject::event()------>

在QWidget::event()函數中,分配給特定的事件處理函數------>

在QButton的事件處理函數中emit(clicked消息)

前面說到了事件的作用,下面來看看我們如何來接收事件。回憶一下前面的代碼,我們在子類中重寫了事件函數,以便讓這些子類按照我們的需要完成某些功能,就像下面的代碼:

  1. void MyLabel::mousePressEvent(QMouseEvent * event)  
  2. {  
  3.         if(event->button() == Qt::LeftButton) {  
  4.                 // do something  
  5.         } else {  
  6.                 QLabel::mousePressEvent(event);  
  7.         }  

上面的代碼和前面類似,在鼠標按下的事件中檢測,如果按下的是左鍵,做我們的處理工作,如果不是左鍵,則調用父類的函數。這在某種程度上說,是把事件向上傳遞給父類去響應,也就是說,我們在子類中“忽略”了這個事件。

我們可以把Qt的事件傳遞看成鏈狀:如果子類沒有處理這個事件,就會繼續向其他類傳遞。其實,Qt的事件對象都有一個accept()函數和ignore()函數。正如它們的名字,前者用來告訴Qt,事件處理函數“接收”了這個事件,不要再傳遞;后者則告訴Qt,事件處理函數“忽略”了這個事件,需要繼續傳遞,尋找另外的接受者。在事件處理函數中,可以使用isAccepted()來查詢這個事件是不是已經被接收了。

事實上,我們很少使用accept()和ignore()函數,而是想上面的示例一樣,如果希望忽略事件,只要調用父類的響應函數即可。記得我們曾經說過,Qt中的事件大部分是protected的,因此,重寫的函數必定存在著其父類中的響應函數,這個方法是可行的。為什么要這么做呢?因為我們無法確認父類中的這個處理函數沒有操作,如果我們在子類中直接忽略事件,Qt不會再去尋找其他的接受者,那么父類的操作也就不能進行,這可能會有潛在的危險。另外我們查看一下QWidget的mousePressEvent()函數的實現:

  1. void QWidget::mousePressEvent(QMouseEvent *event)  
  2. {  
  3.         event->ignore();  
  4.         if ((windowType() == Qt::Popup)) {  
  5.                 event->accept();  
  6.                 QWidget* w;  
  7.                 while ((w = qApp->activePopupWidget()) && w != this){  
  8.                         w->close();  
  9.                         if (qApp->activePopupWidget() == w) // widget does not want to dissappear  
  10.                                 w->hide(); // hide at least  
  11.                 }  
  12.                 if (!rect().contains(event->pos())){  
  13.                         close();  
  14.                 }  
  15.         }  
  16. }  

請注意第一條語句,如果所有子類都沒有覆蓋mousePressEvent函數,這個事件會在這里被忽略掉,這暗示著這個組件不關心這個事件,這個事件就可能被傳遞給其父組件。

不過,事情也不是絕對的。在一個情形下,我們必須使用accept()和ignore()函數,那就是在窗口關閉的時候。如果你在窗口關閉時需要有個詢問對話框,那么就需要這么去寫:

  1. void MainWindow::closeEvent(QCloseEvent * event)  
  2. {  
  3.         if(continueToClose()) {  
  4.                 event->accept();  
  5.         } else {  
  6.                 event->ignore();  
  7.         }  
  8. }  
  9. bool MainWindow::continueToClose()  
  10. {  
  11.         if(QMessageBox::question(this,  
  12.                                             tr("Quit"),  
  13.                                             tr("Are you sure to quit this application?"),  
  14.                                             QMessageBox::Yes | QMessageBox::No,  
  15.                                             QMessageBox::No)  
  16.                 == QMessageBox::Yes) {  
  17.                 return true;  
  18.         } else {  
  19.                 return false;  
  20.         }  

這樣,我們經過詢問之后才能正常退出程序

今天要說的是event()函數。記得之前曾經提到過這個函數,說在事件對象創建完畢后,Qt將這個事件對象傳遞給QObject的event()函數。event()函數并不直接處理事件,而是將這些事件對象按照它們不同的類型,分發給不同的事件處理器(event handler)。

event()函數主要用于事件的分發,所以,如果你希望在事件分發之前做一些操作,那么,就需要注意這個event()函數了。為了達到這種目的,我們可以重寫event()函數。例如,如果你希望在窗口中的tab鍵按下時將焦點移動到下一組件,而不是讓具有焦點的組件處理,那么你就可以繼承QWidget,并重寫它的event()函數,已達到這個目的:

  1. bool MyWidget::event(QEvent *event) {  
  2.         if (event->type() == QEvent::KeyPress) {  
  3.                 QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);  
  4.                 if (keyEvent->key() == Qt::Key_Tab) {  
  5.                         // 處理Tab鍵  
  6.                         return true;  
  7.                 }  
  8.         }  
  9.  
  10.         return QWidget::event(event);  

event()函數接受一個QEvent對象,也就是需要這個函數進行轉發的對象。為了進行轉發,必定需要有一系列的類型判斷,這就可以調用QEvent的type()函數,其返回值是QEvent::Type類型的枚舉。我們處理過自己需要的事件后,可以直接return回去,對于其他我們不關心的事件,需要調用父類的event()函數繼續轉發,否則這個組件就只能處理我們定義的事件了。

event()函數返回值是bool類型,如果傳入的事件已被識別并且處理,返回true,否則返回false。如果返回值是true,QApplication會認為這個事件已經處理完畢,會繼續處理事件隊列中的下一事件;如果返回值是false,QApplication會嘗試尋找這個事件的下一個處理函數。

event()函數的返回值和事件的accept()和ignore()函數不同。accept()和ignore()函數用于不同的事件處理器之間的溝通,例如判斷這一事件是否處理;event()函數的返回值主要是通知QApplication的notify()函數是否處理下一事件。為了更加明晰這一點,我們來看看QWidget的event()函數是如何定義的:

  1. bool QWidget::event(QEvent *event) {  
  2.         switch (e->type()) {  
  3.         case QEvent::KeyPress:  
  4.                  keyPressEvent((QKeyEvent *)event);  
  5.                 if (!((QKeyEvent *)event)->isAccepted())  
  6.                         return false;  
  7.                 break;  
  8.         case QEvent::KeyRelease:  
  9.                 keyReleaseEvent((QKeyEvent *)event);  
  10.                 if (!((QKeyEvent *)event)->isAccepted())  
  11.                         return false;  
  12.                 break;  
  13.                 // more...  
  14.         }  
  15.         return true;  

QWidget的event()函數使用一個巨大的switch來判斷QEvent的type,并且分發給不同的事件處理函數。在事件處理函數之后,使用這個事件的isAccepted()方法,獲知這個事件是不是被接受,如果沒有被接受則event()函數立即返回false,否則返回true。

另外一個必須重寫event()函數的情形是有自定義事件的時候。如果你的程序中有自定義事件,則必須重寫event()函數以便將自定義事件進行分發,否則你的自定義事件永遠也不會被調用。

創建事件過濾器和安裝事件過濾器

Qt創建了QEvent事件對象之后,會調用QObject的event()函數做事件的分發。有時候,你可能需要在調用event()函數之前做一些另外的操作,比如,對話框上某些組件可能并不需要響應回車按下的事件,此時,你就需要重新定義組件的event()函數。如果組件很多,就需要重寫很多次event()函數,這顯然沒有效率。為此,你可以使用一個事件過濾器,來判斷是否需要調用event()函數。

QOjbect有一個eventFilter()函數,用于建立事件過濾器。這個函數的簽名如下:

  1. virtual bool QObject::eventFilter ( QObject * watched, QEvent * event ) 

如果watched對象安裝了事件過濾器,這個函數會被調用并進行事件過濾,然后才輪到組件進行事件處理。在重寫這個函數時,如果你需要過濾掉某個事件,例如停止對這個事件的響應,需要返回true。

  1. bool MainWindow::eventFilter(QObject *obj, QEvent *event)  
  2.  {  
  3.          if (obj == textEdit) {  
  4.                  if (event->type() == QEvent::KeyPress) {  
  5.                          QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);  
  6.                          qDebug() << "Ate key press" << keyEvent->key();  
  7.                          return true;  
  8.                  } else {  
  9.                          return false;  
  10.                  }  
  11.          } else {  
  12.                  // pass the event on to the parent class  
  13.                  return QMainWindow::eventFilter(obj, event);  
  14.          }  
  15.  } 

上面的例子中為MainWindow建立了一個事件過濾器。為了過濾某個組件上的事件,首先需要判斷這個對象是哪個組件,然后判斷這個事件的類型。例如,我不想讓textEdit組件處理鍵盤事件,于是就首先找到這個組件,如果這個事件是鍵盤事件,則直接返回true,也就是過濾掉了這個事件,其他事件還是要繼續處理,所以返回false。對于其他組件,我們并不保證是不是還有過濾器,于是最保險的辦法是調用父類的函數。

在創建了過濾器之后,下面要做的是安裝這個過濾器。安裝過濾器需要調用installEventFilter()函數。這個函數的簽名如下:

  1. void QObject::installEventFilter ( QObject * filterObj ) 

這個函數是QObject的一個函數,因此可以安裝到任何QObject的子類,并不僅僅是UI組件。這個函數接收一個QObject對象,調用了這個函數安裝事件過濾器的組件會調用filterObj定義的eventFilter()函數。例如,textField.installEventFilter(obj),則如果有事件發送到textField組件是,會先調用obj->eventFilter()函數,然后才會調用textField.event()。

當然,你也可以把事件過濾器安裝到QApplication上面,這樣就可以過濾所有的事件,已獲得更大的控制權。不過,這樣做的后果就是會降低事件分發的效率。

如果一個組件安裝了多個過濾器,則最后一個安裝的會最先調用,類似于堆棧的行為。

注意,如果你在事件過濾器中delete了某個接收組件,務必將返回值設為true。否則,Qt還是會將事件分發給這個接收組件,從而導致程序崩潰。

事件過濾器和被安裝的組件必須在同一線程,否則,過濾器不起作用。另外,如果在install之后,這兩個組件到了不同的線程,那么,只有等到二者重新回到同一線程的時候過濾器才會有效。

事件的調用最終都會調用QCoreApplication的notify()函數,因此,最大的控制權實際上是重寫QCoreApplication的notify()函數。由此可以看出,Qt事件處理實際上是分層五個層次:重定義事件處理函數,重定義event()函數,為單個組件安裝事件過濾器,為QApplication安裝事件過濾器,重定義QCoreApplication的notify()函數。這幾個層次的控制權是逐層增大的。

小結:關于QT類 Qevent事件處理過程 事件過濾器 的內容介紹按了,希望本文對你有所幫助。

責任編輯:zhaolei 來源: 互聯網
相關推薦

2011-06-29 16:14:59

Qt 事件 過濾器

2011-07-04 14:00:11

QT QEvent

2021-07-05 15:22:03

Servlet過濾器客戶端

2024-01-05 09:04:35

隆過濾器數據結構哈希函數

2011-07-01 14:20:59

Qt 事件

2011-07-01 14:14:34

Qt 事件

2024-11-04 08:45:48

布隆過濾器元數據指紋值

2009-07-08 16:07:04

Servlet過濾器配

2009-09-29 13:55:23

Hibernate設置

2009-07-14 09:09:08

Swing模型過濾器

2009-07-08 15:30:56

Servlet過濾器

2011-08-29 11:25:29

QTWebKit鼠標

2009-06-18 10:13:00

Hibernate過濾

2025-04-21 00:50:50

2009-09-25 15:19:44

Hibernate過濾

2009-07-08 17:33:37

Servlet過濾器

2017-07-18 14:10:31

大數據Apache Flum過濾器

2011-07-04 14:50:49

QT Event 事件

2011-08-29 14:59:26

QtEvent事件

2011-07-18 10:03:18

CocoaQt
點贊
收藏

51CTO技術棧公眾號

亚洲国产欧美一区二区三区不卡| 成人免费在线视频网| 最新精品国产| 粗暴蹂躏中文一区二区三区| 菠萝蜜视频在线观看www入口| 欧美专区日韩专区| 一级毛片在线| 五月天中文字幕一区二区| av电影免费| 中文字幕日韩av资源站| 91网址在线播放| 国产午夜一区二区三区| 久久精品免费一区二区| 成年人网站91| 日本一级黄视频| 国产盗摄女厕一区二区三区| 视频一区二区视频| 国产制服丝袜一区| 日韩一级特黄毛片| 成人激情午夜影院| 欧美a在线视频| 久久久久88色偷偷免费| 欧美一级在线看| 久久久国产精品午夜一区ai换脸| 国产午夜伦鲁鲁| 久久精品男人天堂av| 欧美午夜aaaaaa免费视频| 中文字幕亚洲成人| 免费观看v片在线观看| 日韩欧美中文字幕在线播放| 国产视频精选在线| 日韩一级大片在线观看| а√天堂中文在线资源8| 亚洲精品色婷婷福利天堂| 日韩一区二区三区在线免费观看 | 一区二区三区高清在线观看| 久国内精品在线| 精品在线91| 91免费版黄色| 青娱乐精品在线视频| 久久综合亚洲精品| 99精品国产99久久久久久白柏| 亚洲少妇久久久| 欧美性生交大片免费| 黄色的视频在线观看| 久久五月天综合| 欧美老女人另类| 日韩成人av网站| 久久久综合视频| 中国一级特黄毛片大片| 欧美色男人天堂| 欧美色网一区| 日本精品视频在线| 香蕉久久夜色精品国产| 妞干网在线视频观看| 亚洲影视在线观看| 八戒八戒神马在线电影| 俺去亚洲欧洲欧美日韩| 欧美一区二区麻豆红桃视频| 日韩一本精品| 国产欧美一区二区精品秋霞影院| 日韩a在线观看| 亚洲一区二区久久| av永久不卡| 午夜精品一区二区三区在线观看 | 日本成人一区二区| 成人午夜一级二级三级| 国产精品一区二区视频| 粉嫩欧美一区二区三区| 亚洲国产99精品国自产| 亚洲视频分类| 18视频在线观看娇喘| 亚洲444eee在线观看| 亚洲电影观看| 国产中文欧美精品| 成人国产一区二区三区精品| 美女欧美视频在线观看免费| 在线日韩欧美视频| 伊人久久大香线| 国产精品宾馆在线精品酒店| 欧美色欧美亚洲另类二区| 北条麻妃一区二区三区在线观看| 奇米视频888战线精品播放| 亚洲欧美激情插| 不卡一二三区| 7777精品久久久大香线蕉小说| 91在线你懂得| 在线电影福利片| 国产va免费精品高清在线观看| 国产麻豆精品theporn| 激情在线视频| 欧美国产一区二区三区| 免费的国产精品| yiren22综合网成人| 欧美影院久久久| 韩国欧美一区二区| 搞黄视频免费在线观看| 久久青草福利网站| 久久成人精品无人区| 校园春色欧美| 欧美激情国内偷拍| 国产精品一二三区在线| 日韩精品久久久免费观看| 亚洲成人黄色| 亚洲欧美国产不卡| 欧美午夜激情小视频| 色狼人综合干| 91高清在线| 久久久免费观看| 久久精品欧洲| 亚洲美女欧洲| 欧美日韩国产成人| 美女黄色成人网| 亚洲sss视频| 日韩av大片在线| 国产亚洲精久久久久久| 人交獸av完整版在线观看| 亚洲精品欧美日韩| 亚洲网友自拍偷拍| 美女av一区| 日本xxxxxxx免费视频| 亚洲乱码av中文一区二区| 新狼窝色av性久久久久久| 四虎精品成人影院观看地址| 国产精品91免费在线| 国产精品国产三级国产aⅴ入口 | 97在线观看视频国产| 日本一区二区三区在线不卡| 亚洲精品一区av| koreanbj精品视频一区| 夜夜嗨av色综合久久久综合网| 国内精品在线播放| 欧美日韩大片| 波多野结衣家庭教师在线| 久久影院资源网| 国产亚洲精品aa| 亚洲制服一区| 老司机色在线视频| 成人久久一区二区| 黑人精品xxx一区| 欧美在线网站| 麻豆网站在线免费观看| 欧美精品一区二区视频| 亚洲国产精品成人av| 久久国产视频网| 日韩久久99| 电影天堂爱爱爱爱| 亚洲专区中文字幕| 欧美猛男gaygay网站| 久久99精品一区二区三区三区| 欧美色999| 天堂色在线视频| 91精品网站| 亚洲国产97在线精品一区| 99re在线精品| 一区二区三区四区在线看| 国产女主播在线直播| 色中色综合成人| 久久精品视频一| 五月天一区二区三区| 久久一区精品| 亚洲精品成人一区| 蜜臀一区二区三区| 免费看污久久久| 视频在线一区二区| 亚洲精品成人天堂一二三| 国内自拍一区| 欧洲一区二区三区精品| 国产国产人免费人成免费视频 | 精品性高朝久久久久久久| 久久久久久免费网| 天天色天天射综合网| 国产白浆在线免费观看| 国产熟人av一二三区| 97在线中文字幕| 在线观看国产欧美| 亚洲一区在线看| 麻豆91小视频| 久久香蕉精品香蕉| 国产在线一区二区视频| 国产又大又硬又粗| 国产一区二区在线观看免费播放| 中文字幕在线国产精品| 亚洲成人一区在线| 久久精品av麻豆的观看方式| 国产成人精品免费视| 小视频免费在线观看| 在线国产小视频| 国产伦精品一区二区三区四区视频_ | 天堂v视频永久在线播放| dy888午夜| 国产日本欧美一区| 亚洲片av在线| 午夜视频一区二区| 成人免费的视频| 国产一区日韩一区| 成人另类视频| japanese色国产在线看视频| 免费在线观看麻豆视频| 男女视频网站在线观看|