免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
QT 消息處理機(jī)制
Qt 事件系統(tǒng) Qt是事件驅(qū)動(dòng)的, 程序每個(gè)動(dòng)作都是由某個(gè)事件所觸發(fā)。 Qt事件的類型很多,我們可以通過查看Qt的 manual中的Event System 和 QEvent 來獲得各個(gè)事件的詳細(xì)信息。

為了完整起見,一份Qt4.6的事件列表附在本文后面。

事件來源
Spontaneous events(自發(fā)事件) 
從系統(tǒng)得到的消息,比如鼠標(biāo)按鍵,鍵盤按鍵等。Qt事件循環(huán)的時(shí)候讀取這些事件,轉(zhuǎn)化為QEvent后依次處理
Posted events 
有Qt或應(yīng)用程序產(chǎn)生,放入消息隊(duì)列
QCoreApplication::postEvent()
Sent events 
由Qt或應(yīng)用程序產(chǎn)生,不放入隊(duì)列,直接被派發(fā)和處理
QCoreApplication::sendEvent()
比如考慮重繪事件處理函數(shù) paintEvent(),3種事件都能使得該函數(shù)被調(diào)用:

當(dāng)窗口被其他窗口覆蓋后,再次重新顯示時(shí),系統(tǒng)將產(chǎn)生 spontaneous 事件來請(qǐng)求重繪
當(dāng)我們調(diào)用 update() 時(shí),產(chǎn)生的是 Posted 事件
當(dāng)我們調(diào)用 repaint() 時(shí),產(chǎn)生的是 Sent 事件
事件派發(fā)事件循環(huán) while (!exit_was_called) {
while (!posted_event_queue_is_empty) {
process_next_posted_event();
}
while (!spontaneous_event_queue_is_empty) {
process_next_spontaneous_event();
}
while (!posted_event_queue_is_empty) {
process_next_posted_event();
}
}
先處理Qt事件隊(duì)列中的事件,直至為空
再處理系統(tǒng)消息隊(duì)列中的消息,直至為空
在處理系統(tǒng)消息的時(shí)候會(huì)產(chǎn)生新的Qt事件,需要對(duì)其再次進(jìn)行處理
不通過事件循環(huán)
sendEvent的事件派發(fā)不通過事件循環(huán)。QApplication::sendEvent()是通過調(diào)用QApplication::notify(),直接進(jìn)入了事件的派發(fā)和處理環(huán)節(jié),是同步的。

sendEvent與postEvent的使用
兩個(gè)函數(shù)都是接受一個(gè) QObject * 和一個(gè) QEvent * 作為參數(shù)。
postEvent 的 event 必須分配在 heep 上。用完后會(huì)被Qt自動(dòng)刪除
sendEvent 的 event 必須分配在 stack 上。
例子(發(fā)送X按鍵事件到mainWin):

QApplication::postEvent(mainWin, new QKeyEvent(QEvent::KeyPress, Key_X, 'X', 0));

QKeyEvent event(QEvent::KeyPress, Key_X, 'X', 0);
QApplication::sendEvent(mainWin, &event);

notify
所有的事件都最終通過 notify 派發(fā)到相應(yīng)的對(duì)象中。

bool QCoreApplication::notify ( QObject * receiver, QEvent * event )事件過濾
看看notify()調(diào)用的內(nèi)部函數(shù)notify_helper()的源碼部分:

先通過 Applicaton 安裝的過濾器
如果未被過濾,再通過 receiver 安裝的過濾器
如果仍未被過濾,才調(diào)用 receiver->event() 函數(shù)進(jìn)行派發(fā)

/*!\internal

Helper function called by notify()
*/
bool QCoreApplicationPrivate::notify_helper(QObject *receiver, QEvent * event)
{
// send to all application event filters
if (sendThroughApplicationEventFilters(receiver, event))
return true;
// send to all receiver event filters
if (sendThroughObjectEventFilters(receiver, event))
return true;
// deliver the event
return receiver->event(event);
}
事件在傳遞到對(duì)象之前(調(diào)用obj->event()函數(shù)之前),要先能通過 Applicaton 和 obj 安裝的過濾器,那么過濾器是怎么安裝的:

首先QObject中有一個(gè)類型為QObjectList的成員變量,名字為eventFilters
當(dāng)某個(gè)QObject安裝了事件過濾器之后, 它會(huì)將filterObj的指針保存在eventFilters中

monitoredObj->installEventFilter(filterObj);
在事件到達(dá)QObject::event()函數(shù)之前,會(huì)先查看該對(duì)象的eventFilters列表, 如果非空, 就先調(diào)用列表中對(duì)象的eventFilter()函數(shù).

bool QObject::eventFilter ( QObject * watched, QEvent * event )
事件過濾器函數(shù)eventFilter()返回值是bool型 
如果返回true, 則表示該事件已經(jīng)被處理完畢, Qt將直接返回, 進(jìn)行下一事件的處理
如果返回false, 事件將接著被送往剩下的事件過濾器或是目標(biāo)對(duì)象進(jìn)行處理
對(duì)于 QCoreApplication ,由于也是QObject 派生類,安裝過濾器方式與前述相同。

事件轉(zhuǎn)發(fā)
對(duì)于某些類別的事件, 如果在整個(gè)事件的派發(fā)過程結(jié)束后還沒有被處理, 那么這個(gè)事件將會(huì)向上轉(zhuǎn)發(fā)給它的父widget, 直到最頂層窗口.

如何判斷一個(gè)事件是否被處理了呢? (有兩個(gè)層次)

QApplication::notify(), QObject::eventFilter(), QObject::event() 通過返回bool值來表示是否已處理. “真”表示已經(jīng)處理, “假”表示事件需要繼續(xù)傳遞
另一種是調(diào)用QEvent::ignore() 或 QEvent::accept() 對(duì)事件進(jìn)行標(biāo)識(shí),accept表示事件被處理
為清楚起見,貼一點(diǎn)Qt的源碼(來自 QApplication::notify()):

case QEvent::ToolTip:
case QEvent::WhatsThis:
case QEvent::QueryWhatsThis:
{
QWidget* w = static_cast<QWidget *>(receiver);
QHelpEvent *help = static_cast<QHelpEvent*>(e);
QPoint relpos = help->pos();
bool eventAccepted = help->isAccepted();
while (w) {
QHelpEvent he(help->type(), relpos, help->globalPos());
he.spont = e->spontaneous();
res = d->notify_helper(w, w == receiver ? help : &he);
e->spont = false;
eventAccepted = (w == receiver ? help : &he)->isAccepted();
if ((res && eventAccepted) || w->isWindow())
break;

relpos += w->pos();
w = w->parentWidget();
}
help->setAccepted(eventAccepted);
}
break;
這兒顯示了對(duì) WhatsThis 事件的處理:先派發(fā)給 w,如果事件被accepted 或已經(jīng)是頂級(jí)窗口,則停止;否則獲取w的父對(duì)象,繼續(xù)派發(fā)。

事件處理
重新實(shí)現(xiàn)一個(gè)特定的事件handler
QObject與QWidget提供了許多特定的事件handlers,分別對(duì)應(yīng)于不同的事件類型。(如paintEvent()對(duì)應(yīng)paint事件)

重新實(shí)現(xiàn)QObject::event()
event()函數(shù)是所有對(duì)象事件的入口,QObject和QWidget中缺省的實(shí)現(xiàn)是簡(jiǎn)單地把事件推入特定的事件handlers。

在QObject安裝上事件過濾器
事件過濾器是一個(gè)對(duì)象,它接收別的對(duì)象的事件,在這些事件到達(dá)指定目標(biāo)之間。

在aApp上安裝一個(gè)事件過濾器,它會(huì)監(jiān)視程序中發(fā)送到所有對(duì)象的所有事件
重新實(shí)現(xiàn)QApplication:notify(),Qt的事件循環(huán)與sendEvent()調(diào)用這個(gè)函數(shù)來分發(fā)事件,通過重寫它,你可以在別人之前看到事件。
事件列表
Qt4.6的事件列表:

QAccessibleEvent
QActionEvent
QChildEvent
QCloseEvent
QCustomEvent
QDragLeaveEvent
QDropEvent 
QDragMoveEvent 
QDragEnterEvent
QDynamicPropertyChangeEvent
QFileOpenEvent
QFocusEvent
QGestureEvent
QGraphicsSceneEvent 
QGraphicsSceneContextMenuEvent
QGraphicsSceneDragDropEvent
QGraphicsSceneHelpEvent
QGraphicsSceneHoverEvent
QGraphicsSceneMouseEvent
QGraphicsSceneMoveEvent
QGraphicsSceneResizeEvent
QGraphicsSceneWheelEvent.
QHelpEvent
QHideEvent
QHoverEvent
QIconDragEvent
QInputEvent 
QContextMenuEvent
QKeyEvent
QMouseEvent
QTabletEvent
QTouchEvent
QWheelEvent
QInputMethodEvent
QMoveEvent
QPaintEvent
QResizeEvent
QShortcutEvent
QShowEvent
QStatusTipEvent
QTimerEvent
QWhatsThisClickedEvent
QWindowStateChangeEvent

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
QT父子窗口事件傳遞與事件過濾器
Qt學(xué)習(xí)之路(22): 事件過濾器
Qt事件過濾器eventFilter的使用方式
第七章 Qt事件(event)處理
Qt 5——Qt消息機(jī)制和事件(二)
[Qt] postevent emit
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服