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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

Qt事件体系概述(The Event System)

發布時間:2023/12/20 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Qt事件体系概述(The Event System) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文譯自https://doc.qt.io/qt-5/eventsandfilters.html,是意譯。

目錄

事件的發送(How Events are delivered)

事件類型(Event Types)

事件處理器(Event Handlers)

事件過濾器(Event filters)

發送事件(Sending Events)


In Qt, events are objects, derived from the abstract?QEvent?class, that represent things that have happened either within an application or as a result of outside activity that the application needs to know about. Events can be received and handled by any instance of a?QObject?subclass, but they are especially relevant to widgets. This document describes how events are delivered and handled in a typical application.

Qt的事件都是派生自QEvent的對象。QEvent類代表應用程序內部發生的事情,或者代表程序需要知悉的一些外部活動的結果。事件可以被任何的QObject的派生類接收、處理,但是尤其事件都跟QWidget有關。本文介紹事件被程序發送、處理的典型流程。

事件的發送(How Events are delivered)

When an event occurs, Qt creates an event object to represent it by constructing an instance of the appropriate?QEvent?subclass, and delivers it to a particular instance of?QObject?(or one of its subclasses) by calling its?event()?function.

This function does not handle the event itself; based on the type of event delivered, it calls an event handler for that specific type of event, and sends a response based on whether the event was accepted or ignored.

Some events, such as?QMouseEvent?and?QKeyEvent, come from the window system; some, such as?QTimerEvent, come from other sources; some come from the application itself.

事件發生時,qt產生一個相應的QEvent派生類實例,然后通過調用event()函數把事件發送給某個QObject或者其派生類。

event函數并不處理事件,而是根據事件類型調用相應的event handler,然后根據事件被接受(accept)還是忽略(ignore)來發送一個響應。

有的事件來自窗體系統,如鼠標事件、鍵盤事件。還有的如定時器事件來自其他源頭。還有的來自程序自身。

事件類型(Event Types)

大多數事件都有獨特的類與之對應,如鼠標事件,重繪事件等。每一個類都繼承自QEvent,但是在其基礎上添加了函數。比如說,QResizeEvent添加了size() 和 oldSize()函數來描述窗體尺寸的變化。

有的事件可以描述多種不同的事件。如QMouseEvent,可以用來描述鼠標按下、雙擊、光標移動等。

所有事件的類型都通過QEvent::Type來描述。利用這個特性,可以在運行時快速的確定該事件屬于哪個類型。

由于程序的行為復雜多變,qt的事件發送機制也很有彈性。發送機制的描述在QCoreApplication::notify()的文檔中有具體描述。而另一篇文章<<Another Look At Events>>則差一些。下面的關于事件發送機制的描述將覆蓋95%的情況。

事件處理器(Event Handlers)

The normal way for an event to be delivered is by calling a virtual function. For example,?QPaintEvent?is delivered by calling?QWidget::paintEvent(). This virtual function is responsible for reacting appropriately, normally by repainting the widget. If you do not perform all the necessary work in your implementation of the virtual function, you may need to call the base class's implementation.

For example, the following code handles left mouse button clicks on a custom checkbox widget while passing all other button clicks to the base?QCheckBox?class:

正常情況下發送事件的辦法是調用虛函數。比如,QPaintEvent通過paintEvent()發送。這個虛函數通常用來重繪界面。假如你沒有重寫虛函數,你或許應調用基類的虛函數。

下面的例子中,MyCheckBox繼承了QCheckBox,重寫了鼠標左鍵點擊checkbox的的行為,而其他類型的點擊仍通過基類QCheckBox實現:

void MyCheckBox::mousePressEvent(QMouseEvent *event) {if (event->button() == Qt::LeftButton) {// handle left mouse button here} else {// pass on other buttons to base classQCheckBox::mousePressEvent(event);} }

If you want to replace the base class's function, you must implement everything yourself. However, if you only want to extend the base class's functionality, then you implement what you want and call the base class to obtain the default behavior for any cases you do not want to handle.

Occasionally, there isn't such an event-specific function, or the event-specific function isn't sufficient. The most common example involves Tab key presses. Normally,?QWidget?intercepts these to move the keyboard focus, but a few widgets need the Tab key for themselves.

These objects can reimplement?QObject::event(), the general event handler, and either do their event handling before or after the usual handling, or they can replace the function completely. A very unusual widget that both interprets Tab and has an application-specific custom event might contain the following?event()?function:

假如你想替代基類的函數,就必須完全重寫。假如你想在基類的基礎上做功能擴展,那么你可以寫出你的新功能,并調用基類的虛函數來保持對其他功能的默認實現。

個別事件是沒有對應的響應函數的。最常見的例子是Tab鍵按下這個事件。通常QWidget截獲這個事件,然后執行焦點轉移。很少有窗體需要響應tab事件本身。

響應此類事件可以通過重寫QObject::event()完成。重寫可以發生在正常的事件響應之前或者之后,或者完全覆蓋QObject::event()。下面的代碼展示了一種罕見的窗體,既能截獲Tab,同時又處理自定義的事件:

bool MyWidget::event(QEvent *event) {if (event->type() == QEvent::KeyPress) {QKeyEvent *ke = static_cast<QKeyEvent *>(event);if (ke->key() == Qt::Key_Tab) {// special tab handling herereturn true;}} else if (event->type() == MyCustomEventType) {MyCustomEvent *myEvent = static_cast<MyCustomEvent *>(event);// custom event handling herereturn true;}return QWidget::event(event); }

Note that?QWidget::event() is still called for all of the cases not handled, and that the return value indicates whether an event was dealt with; a?true?value prevents the event from being sent on to other objects.

注意,其他沒有被處理的事件交給了QWidget::event()。QWidget::event()的返回值說明了事件是否被處理了。返回值為真,說明已經被處理,這樣事件就不會發送到其他object了。

事件過濾器(Event filters)

Sometimes an object needs to look at, and possibly intercept, the events that are delivered to another object. For example, dialogs commonly want to filter key presses for some widgets; for example, to modify Return-key handling.

The?QObject::installEventFilter() function enables this by setting up an?event filter, causing a nominated filter object to receive the events for a target object in its?QObject::eventFilter() function. An event filter gets to process events before the target object does, allowing it to inspect and discard the events as required. An existing event filter can be removed using the?QObject::removeEventFilter() function.

When the filter object's?eventFilter()?implementation is called, it can accept or reject the event, and allow or deny further processing of the event. If all the event filters allow further processing of an event (by each returning?false), the event is sent to the target object itself. If one of them stops processing (by returning?true), the target and any later event filters do not get to see the event at all.

?有的對象需要檢查或者截獲發向其他對象的事件。比如說,對話框都想過濾一些widget的按鍵事件;又比如修改回車鍵響應。

QObject::installEventFilter()函數令被點名的過濾器對象在目標對象的eventFilter()函數中接收事件。過濾器在目標對象處理事件之前就已經處理了事件。過濾器通過removeEventFilter來移除。

重寫eventFilter時,事件既可以被接收,也可以被拒絕;既可以允許其走向下一個對象,也可以終止其繼續傳遞。如果所有的過濾器都允許事件繼續傳遞(通過設置返回值為假),事件就被送到了目標對象處。假如中途某個過濾器返回了真,則后面的過濾器和目標對象都不會看到這個事件。

bool FilterObject::eventFilter(QObject *object, QEvent *event) {if (object == target && event->type() == QEvent::KeyPress) {QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);if (keyEvent->key() == Qt::Key_Tab) {// Special tab handlingreturn true;} elsereturn false;}return false; }

The above code shows another way to intercept Tab key press events sent to a particular target widget. In this case, the filter handles the relevant events and returns?true?to stop them from being processed any further. All other events are ignored, and the filter returns?false?to allow them to be sent on to the target widget, via any other event filters that are installed on it.

It is also possible to filter?all?events for the entire application, by installing an event filter on the?QApplication?or?QCoreApplication?object. Such global event filters are called before the object-specific filters. This is very powerful, but it also slows down event delivery of every single event in the entire application; the other techniques discussed should generally be used instead.

上面的代碼展示了另一種截獲tab按鍵事件的辦法。過濾器處理tab事件,并返回真。真意味著此事件被過濾器處理后不再向后傳遞。其他的事件返回假,所以將繼續向目標Widget傳遞。

你也可以在QApplication或者QCoreApplication上按裝過濾器,整個應用程序的事件都會被此過濾器處理。這種全局的過濾器將在具體對象的過濾器之前被調用。這個方法固然強大,但也會使應用程序的事件處理放緩。

發送事件(Sending Events)

Many applications want to create and send their own events. You can send events in exactly the same ways as Qt's own event loop by constructing suitable event objects and sending them with?QCoreApplication::sendEvent() and?QCoreApplication::postEvent().

sendEvent()?processes the event immediately. When it returns, the event filters and/or the object itself have already processed the event. For many event classes there is a function called?isAccepted()?that tells you whether the event was accepted or rejected by the last handler that was called.

postEvent()?posts the event on a queue for later dispatch. The next time Qt's main event loop runs, it dispatches all posted events, with some optimization. For example, if there are several resize events, they are compressed into one. The same applies to paint events:?QWidget::update() calls?postEvent(), which eliminates flickering and increases speed by avoiding multiple repaints.

postEvent()?is also used during object initialization, since the posted event will typically be dispatched very soon after the initialization of the object is complete. When implementing a widget, it is important to realize that events can be delivered very early in its lifetime so, in its constructor, be sure to initialize member variables early on, before there's any chance that it might receive an event.

To create events of a custom type, you need to define an event number, which must be greater than?QEvent::User, and you may need to subclass?QEvent?in order to pass specific information about your custom event. See the?QEvent?documentation for further details.

許多應用需要創建并發送自己的事件。你可以像qt自己的事件循環一樣來創建合適的事件對象,并利用QCoreApplication::sendEvent, QCoreApplication::postEvent來發送它們。

sendEvent()函數返回時,事件已經被處理完成了。很多事件類都有isAccepted()方法,告知事件最終被接受還是拒絕。

postEvent()函數則將事件放入隊列,留待稍后分發。當qt的事件循環開始新一輪處理時,將分發所有的事件。分發過程可能會被優化。比如說,假如隊列里有多個resize事件,則這些事件將壓縮為一個再分發。QWidget::update()也采用類似方式:這樣可以避免閃爍,并增加處理速度。

postEvent也在對象初始化過程中被調用。在實例化一個窗體時,要注意窗體創建不久,就會有事件發送出去。所以要確保窗體的成員今早初始化,以免沒有初始化的成員卷入事件處理中。

自定義事件類型時,你需要給事件一個編號。編號必須大于QEvent::User。而且你或許要繼承QEvent,在派生類里添加一些信息。具體可參閱QEvent文檔。

總結

以上是生活随笔為你收集整理的Qt事件体系概述(The Event System)的全部內容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 精品国自产拍在线观看 | 国产精品揄拍100视频 | 欧美性大战久久久久久久 | 久久中文字幕av | 波多野吉衣一区二区 | 韩国伦理片在线播放 | 九九热在线观看视频 | 日本不卡一 | 亚洲精选一区 | 亚洲成av人片一区二区梦乃 | 天天想你在线观看完整版电影高清 | 黄色a级片| 成年人网站在线观看视频 | 性欧美69 | 一区二区高清在线观看 | 在线观看国产网站 | 久久免费少妇高潮久久精品99 | 五十路毛片 | 午夜伊人网 | 综合色区 | 深夜福利免费视频 | 日韩理论在线 | 久久久久中文字幕亚洲精品 | 午夜不卡久久精品无码免费 | 日日射夜夜 | 亚洲av无码一区二区三区人妖 | 亚洲精品乱码久久久久久不卡 | 久久久无码18禁高潮喷水 | 久久久综合 | 久久久精品毛片 | 1024毛片基地| 亚洲男人天堂 | 97成人人妻一区二区三区 | 亚洲成人黄色网 | 黄色网日本 | 亚洲精品欧美精品 | 天天爽影院 | 精品色综合| 久久久综合 | 亚洲精品456 | 波多野结衣视频观看 | 日韩精品一区二区视频 | 日本中文字幕网 | 在线观看9.1| 精品九九在线 | 青青青手机视频在线观看 | 超碰免费在线97 | 蜜臀av性久久久久蜜臀aⅴ流畅 | 九一福利视频 | 欧洲国产视频 | 欧美做受高潮中文字幕 | 欧美在线免费看 | 人人妻人人澡人人爽 | 色丁香六月 | 午夜欧美福利 | 日韩人妻精品一区二区 | 黄色男同视频 | 日日噜噜夜夜狠狠久久丁香五月 | 日韩a级片| 成人性做爰aaa片免费看不忠 | 欧美高清精品一区二区 | 夜夜撸av| 嫩草在线观看 | 国产精品日韩欧美一区二区三区 | 成人性生交视频免费观看 | 浪潮av一区二区三区 | 国产黄色小视频在线观看 | 国产精品第2页 | 大香蕉视频一区二区 | 一区二区在线观看视频 | wwwxxxx在线观看 | 在线黄色av网站 | 波多野一区二区 | 日本一本在线观看 | аⅴ资源中文在线天堂 | 久精品在线观看 | 强行糟蹋人妻hd中文 | 一级a性色生活片久久无 | 国产精品日本一区二区在线播放 | 亚洲精品色图 | 精品久久亚洲 | 久久久久成人精品无码 | 国产乱xxⅹxx国语对白 | 91在线精品一区二区三区 | 亚洲色图吧 | 午夜视频一区二区 | 激情综合激情五月 | 免费看欧美一级片 | 看黄色一级片 | 日韩精品一区二区三区在线观看 | 精品无码国产av一区二区三区 | 亚洲AV午夜成人片 | 毛片一级片 | 国产调教在线观看 | 天天操,夜夜操 | 在线二区 | 五月激情丁香婷婷 | 久久久久人妻精品一区二区三区 | 国产美女主播在线观看 |