詳解關(guān)于Qt中Event事件處理流程
Qt中Event處理流程是本文要介紹的內(nèi)容,主要是來了解Event事件的處理。在Qt/Embedded中,鼠標(biāo)事件來自于觸摸屏設(shè)備。在使用select讀取觸摸屏設(shè)備中的數(shù)據(jù)后(即采樣,壓力達(dá)到一定閾值),處理些采樣點(diǎn)后得到一個(gè)物理設(shè)備坐標(biāo)點(diǎn),然后用QCoreApplication的sendEvent活postEvent將其發(fā)送出去,于是Event的處理流程就開始了。
首先,QCoreApplication::notify將event直接傳遞給接受者。重新實(shí)現(xiàn)它,可以截取系統(tǒng)所有需要處理的事件。
其次,在使用notify通知接受者處理后,可以為application的實(shí)例qApp安裝一個(gè)event filter,它將處理應(yīng)用程序范圍內(nèi)的事件。
第三,event在經(jīng)過application的處理后,到達(dá)QObject的event filter列表,為接收者者們安裝event filter,將只處理發(fā)給自己的各個(gè)事件。
第四,在經(jīng)過上述處理后,event到達(dá)QObject的event函數(shù)。該函數(shù)處理發(fā)送給自己的event,如QWidget中它按照event類型分發(fā)給自己的各個(gè)event Handler,如MouseReleaseEvent,KeyPressEvent等。
***,是處理不同類型event的event handler。這也是經(jīng)常使用的,它只處理自己的event。
過程如下:
- bool QCoreApplication::notify (
- QObject
- * receiver, QEvent
- * event
- )
- ->qApp
- 的
- event filters->object
- 的
- event filter->object
- 的event()
- 函數(shù)->object
- 的各
- event handler
在以上處理過程中,返回true表示中止事件的處理,返回false則繼續(xù)。
父子窗體傳遞關(guān)系:
對于構(gòu)成parent-child關(guān)系的QWidget,事件將首先傳遞給child,在子窗體做出ignore后將繼續(xù)傳遞給父窗體,若是accept,將終止傳
遞。若我們想截獲發(fā)給父窗體容器中的各個(gè)子(孫)窗體的event,可以使用QObject::findChildren查找出child列表,為其安裝event filter。比如自己重載eventfilter函數(shù),然后安裝它就行了。當(dāng)然,也可以在繼承的子類的event handler中ignore后讓父窗體繼續(xù)處理,但這不是截獲。
注意:根據(jù)Qt文檔,安裝的event filter不支持另外一個(gè)線程中執(zhí)行的object。
應(yīng)用實(shí)例:
FileBrowser中包含有多個(gè)QPushButton和一個(gè)QFrame,QFrame包含一個(gè)QStackedWidget,后者包含一個(gè)QListView和一個(gè)QTreeView兩個(gè)widget(它們是)。Filebrowser實(shí)現(xiàn)了eventFilter,并在FileBrowser的構(gòu)造函數(shù)中安裝它們:
- this->installEventFilter(this);
- listView->installEventFilter(this);//not work,why?
- treeView->installEventFilter(this);//not work,why?
- QList<QPushButton*> allButtons = this->findChildren<QPushButton *>();
- foreach(QPushButton* button, allButtons)
- button->installEventFilter(this);
運(yùn)行結(jié)果如下:
- obj name1:FileBrowserListView, type: 8
- event filter: pid=6273 tid=-1208457520
- ListView::mouseReleaseEvent: pid=6273 tid=-1208457520
問題:
前兩行為eventfilter中的輸出結(jié)果:表示截取到了發(fā)往ListView的事件(類型為8,F(xiàn)ocusIn事件)。而第三行則是listView的event handler的輸出,它能夠處理mouse、release事件,但event filter并未捕獲到它,但可以捕獲到焦點(diǎn)的得失事件。輸出的線程號(hào)也是相同的。
為什么event filter不能捕獲兩個(gè)view上的鼠標(biāo)點(diǎn)擊事件,但可以獲取其它事件如FocusIn與FocusOut呢?
其中輸出log的代碼是:
- #include<unistd.h>
- //#include<sys/types.h>
- #include <pthread.h>
- ...
- fprintf(stderr, "ListView::mouseReleaseEvent: pid=%d tid=%d\n",::getpid(), (unsigned int)::pthread_self()/*::gettid()*/);
小結(jié):詳解關(guān)于Qt中Event處理流程的內(nèi)容介紹完了,希望通過本文的學(xué)習(xí)能對你有所幫助!