[Qt] Qt event system

00. Catalog

insert image description here

01. Overview of Qt event system

Qt 5.12

​ Qt Core

​ The Event System

In Qt, events are objects, derived from the abstract QEvent class, that represent something happening inside the application or the result of external activity that the application needs to know about. Events can be received and handled by any QObject subclass, but they are particularly relevant to widgets. This document describes how events are delivered and handled in a typical application.

02. How events are delivered

When an event occurs, Qt creates an event object to represent it by constructing an appropriate instance of the QEvent subclass and passing it to QObject (or one of its subclasses) via

By calling its event() function.

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

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

03. Event type

There are special classes for most event types, notably QResizeEvent , QPaintEvent , QMouseEvent , QKeyEvent , and QCloseEvent . Each QEvent subclass does

Add functions for specific events. For example QResizeEvent increases size() and oldSize() to enable widgets to discover how their size has changed.

Certain classes support multiple actual event types. QMouseEvent supports mouse button down, double click, move and other related operations.

Each event has an associated type, defined in QEvent::Type , which can be used as a convenient source of runtime type information to quickly determine which event object a given event object was constructed from

Subclass.

Since programs need to react in various complex ways, Qt's event delivery mechanism is very flexible. QCoreApplication::notify () related documentation succinctly describes the whole process

Cheng; The Qt Quarterly article Another Look at Events recaps it succinctly. Here we will explain enough for 95% of the applications.

04. Event handling

The normal way to deliver events is to call virtual functions. For example a QPaintEvent is passed by calling the QWidget::paintEvent () method. This virtual function is responsible for making the appropriate

Reaction, usually by repainting the widget control. If all necessary work is not performed in the virtual function's implementation, it may be necessary to call the base class's implementation.

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

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

If you want to replace the functionality of the base class, you have to implement everything yourself. However, if you just want to extend the functionality of the base class, then you can achieve what you want, and call the base class to get

Take the default behavior for any cases you don't want to handle.

Sometimes there is no such event-specific function, or an event-specific function is not enough. The most common example involves pressing the Tab key. Usually QWidget intercepts these to move the keyboard

focus, but some controls require the Tab key.

These objects can reimplement QObject::event (), regular event handlers, and their event handling can be performed before or after regular processing, or they can completely reimplement

write function. A very unusual widget that both interprets Tab and has application-specific custom events might contain the following event() function

 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 here
             return true;
         }
     } else if (event->type() == MyCustomEventType) {
         MyCustomEvent *myEvent = static_cast<MyCustomEvent *>(event);
         // custom event handling here
         return true;
     }

     return QWidget::event(event);
 }

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

05. Event filter

Sometimes an object needs to see (and possibly intercept) an event passed to another object. For example, dialog boxes often need to filter the keystrokes of certain Widget controls; for example, modifying the return key

event handling.

The QObject::installEventFilter() function does this by setting up an event filter so that the specified filter object receives the target event in its QObject::eventFilter() function.

event of the target object. Event filters process events before they are processed by the target object, allowing it to inspect and discard events as necessary. Existing event filters can use

The QObject::removeEventFilter() function removes.

When a filter object's eventFilter() is called, it can accept or reject the event, and allow or deny further processing of the event. If all event filters allow event

For further processing (each filter usually returns false), the event is sent to the target object itself. If one of them stops processing (by returning true), the target and any subsequent

The event filter cannot see the event at all.

 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 handling
             return true;
         } else
             return false;
     }
     return false;
 }

The code above shows another way to intercept the Tab key press event sent to a specific target widget control. In this case, the filter handles the relevant event and returns true to prevent

prevent them from being further processed. All other events are ignored and the filter returns false to allow them to be sent to the target control via any other event filters installed on the target control.

pieces.

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 object-specific filters. This is very powerful, but it also slows down event delivery for every event in the entire application; using other techniques should generally be discussed.

06. Event sending

Many applications wish to create and send their own events. By constructing a suitable event object and using QCoreApplication::sendEvent() and

QCoreApplication::postEvent() sends events, and you can post events in exactly the same way as Qt's own event loop.

sendEvent() handles the event immediately. When it returns, the event filter and/or the object itself has processed the event. For many event classes, there is a function called isAccepted()

number, which tells you whether the event was accepted or rejected by the last handler called.

postEvent() sends the event to the queue for later dispatch. The next time Qt's main event loop runs, it dispatches all posted events, with some optimizations. For example, if

There are multiple resize events and they will be compressed into one event. The same applies to paint events: QWidget::update() calls postEvent(), which eliminates the flicker and by avoiding

Multiple redraws improve speed.

postEvent() is also used during object initialization, since posted events are usually dispatched soon after object initialization completes. When implementing a widget, it's important to realize that events can be delivered early in its life cycle, so in its constructor, be sure to initialize member variables early so that it doesn't have the potential to receive events.

To create a custom type of event, you need to define an event number that must be greater than QEvent::User, and you may need to create a subclass of QEvent in order to pass the

Information specific to custom events. See the QEvent documentation for details.

appendix

Key words:The Event System

Reference: The Event System

Guess you like

Origin blog.csdn.net/dengjin20104042056/article/details/132447669