The QT Event System

Source: Internet
Author: User

Briefly

In Qt, an event is an object derived from the Qevent abstract class that represents an event that occurs in an application or an event generated by an external activity that the application needs to handle.

Events can be received and processed by any qobject-derived subclass instance object, but they are associated to a particular control. Below, we mainly describe how event is sent and processed in a typical application.

    • Briefly
    • How events are Sent
    • Event Type
    • Event handlers
    • Event filters
    • Send Event
    • More references

How events are Sent

Typically, when an event occurs, QT represents the occurrence of an event by constructing an appropriate Qevent subclass object, and then sends the event object to a specific qobject (or its subclasses) object by invoking the events () function.

Instead of handling the event itself, this function first checks the received event type and then invokes the corresponding event handler based on the event type, which returns a bool value after the event handler indicates whether the event was accepted or ignored.

Some events, such as: Qmouseevent and Qkeyevent, come from the windowing system; some, such as: Qtimerevent, come from other sources of events; some, from the application itself.

Event Type

QT has set up the corresponding classes for most event types, common: Qresizeevent, qpaintevent, Qmouseevent, Qkeyevent, Qcloseevent.

Each particular event class inherits from Qevent and adds a specific event function. For example: Qresizeevent added size () and oldsize () so that the controls can see how their dimensions have changed.

Some classes actually support more than one event type. Qmouseevent supports events that are raised by mouse button presses, double-click events, move events, and other related actions.

Each event has an associated type, defined by Qevent::type, that allows the runtime to easily detect the event type of each event object to quickly determine which event class the event object is constructed from.

Because the program needs to interact with multiple and complex events, QT's event sending mechanism is designed to be very flexible.

The Qcoreapplication::notify () document provides a concise description of the entire mechanism:

boolevent) [virtual]

Send event to Recipient: Receiver->event (event). Returns the value returned from the receiver's event handler. Note that this function applies to any object in any thread in the application. For a specific type of event (for example, mouse and keyboard events), the event is routed to the recipient's parent and uploaded in this way.

Until the top-level object is reached, if the recipient does not process the event (for example, return false).

A total of five ways to handle events, overriding qcoreapplication::notify () is just one of them. These five methods are listed below:

    1. Rewrite PaintEvent (), Mousepressevent (), and so on. This is the most commonly used, simplest but also the most limited way.

    2. Rewrite Qcoreapplication::notify (). This is very powerful and gives you complete control over event handling, but it can only be used for one subclass at a time.

    3. Install an event filter for Qcoreapplication::instance (). This event filter can handle all events of all controls, so this is as powerful as rewriting notify (), and there can be more than one application global event filter, and the application global event filter can even receive mouse events for disabled controls.

      Note: Application-level Event filters can only be used for objects that survive in the main thread.

    4. Rewrite Qobject::event () (like Qwidget). If you rewrite qobject::event (), when the TAB key is pressed, you can handle the event before any control-level event filter captures the TAB key press event.

    5. Installs an event filter for the corresponding receiving object. For example: an event filter that captures all events, including the tab and Shift+tab key press events, before they change the focus control.

      Please also refer to: Qobject::event () and Installeventfilter ().

Event handlers

The standard way to handle events is to call a virtual function. For example: Qpaintevent is handled by calling Qwidget::p aintevent (). This virtual function is responsible for the corresponding processing, usually redrawing the control. If you do not do all the necessary work in the virtual function you implement, you need to invoke its base class implementation.

For example, the following code handles the left mouse click event for a custom CheckBox control and forwards all other click events to its base class Qcheckbox:

void MyCheckBox::mousePressEvent*event){    if (event->== Qt::LeftButton) {        // 处理鼠标左键    else {        // 传递其它按键给基类        QCheckBox::mousePressEvent(event);    }}

If you need to replace the function of the base class, you should implement all the related processing yourself. However, if you only want to extend the functionality of the base class, you only need to implement the part that you want to implement, and then call the base class handler to handle the situation you do not intend to handle.

Occasionally, you have to deal with a specific event that does not have a corresponding handler function, or if you encounter an event handler function that is not sufficient. The most common example is the TAB key press event. Typically, when qwidget intercepts the TAB key, the keyboard focus is moved, but a few controls need to handle the event on their own. These objects can override the Qobject::event () function, a generic event handler, and then write their own event-handling procedures before or after the usual process, or completely replace the original process. The following is a very common control:

The

handles the tab event on its own and handles some key events on its own, and forwards other events that do not need to be handled by itself to the base class:

bool  MyWidget:: Event (Qevent *event) {if  (event->type () = = qevent::keypress) {Qkeyevent *ke =    static_cast  <qkeyevent *> (event); if  (Ke->key () = = Qt::key_tab) {//special tab action  return  true ; }} else  if  (event->type () = = Mycustomeventtype) {mycustomevent *myevent = static_cast  <mycustomevent *> (    event);    //custom event handling  return     true ; } return  qwidget::event (event);}  

Note: Qwidget::event () is still called on an event that is not processed and returns the return value of the base class call to indicate whether the event has been processed or, if true, to prevent the event from being sent to another object.

Event filters

Sometimes an object needs to be checked and it may intercept events destined for other objects. For example, dialogs often need to filter events destined for certain controls, such as changing the event handling of the ENTER key press.

By invoking the Qobject::installeventfilter () function of the filter object, an event filter is set for the target object, and the event destined to the target object is processed in the Qobject::eventfilter () function of the filter object. An event filter handles events before the target object receives an event, which allows the filter object to inspect and discard events when needed. You can call Qobject::removeeventfilter () to remove an already installed event filter.

When the EventFilter () implementation of the filter is invoked, it can choose to handle the event or forward the event, or prevent the event from continuing to be processed by other objects. If all event filters allow an event to be processed (returning false after each filter is processed), the event will eventually be sent to the target object. If one of them aborts the process (by returning True), the subsequent filter object and the target object will not receive the event.

bool FilterObject::eventFilter(QObject *object, QEvent *event){    if (object == target && event->type() == QEvent::KeyPress) {        static_cast<QKeyEvent *>(event);        if (keyEvent->key() == Qt::Key_Tab) {            // 特别的Tab操作            returntrue;        else            returnfalse;    }    returnfalse;}

The code above demonstrates another way to intercept a tab event to a particular object. In this example, the filter returns true after processing the tab event to prevent them from being processed. All other key events are ignored, and then the filter returns false to allow the event to be processed by a subsequent filter that is already installed, and eventually to the target control.

In addition, you can filter all events for the entire application by simply installing the filter object on the Qapplication or Qcoreapplication object. Such a global event filter is called before any object-level filter is called.

This is very powerful, but it also slows down every process for each event in the application-wide context, often using other techniques instead.

Send Event

Many applications need to create and send their own events. You can completely imitate Qt's own event loop mechanism, construct the appropriate event object first, then call Qcoreapplication::sendevent () and qcoreapplication::p ostevent () sends the constructed event to the specified recipient.

Sendevent () immediately synchronously processes the event to be sent. When it returns, it indicates that the event filter and/or target object has been disposed of. For most event classes, there is a function called isaccepted () that can be used to determine whether the event has been accepted for processing or rejected.

Postevent () submits the event to a queue for scheduling. The next time the main event loop of QT runs, all events committed to the queue are dispatched in an optimized manner. For example, if there are several size change events, they will be compressed into an event. The same applies to drawing events: Qwidget::update () calls postevent () to avoid multiple redraw to eliminate flicker and increase speed.

Postevent () is also used for the initialization of an object, because the submitted event is usually dispatched within a very short period of time after the corresponding object has been initialized. When implementing a control, it is important to support the event mechanism early in the constructor of the custom control, ensuring that member variables are initialized as early as possible before any events can be accepted.

To create a custom event, you need to define an event number that is greater than qevent::user and may need to inherit qevent to pass specific information about the type of event you have customized.

More references
    • The Event SYSTEM-QT Assistant

Qt Event System

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.