QT Learning Events and event filters (divided into five levels)

Source: Internet
Author: User

Event

In QT, events are handled as objects, and all event objects inherit from the abstract class qevent. This class is used to denote actions that occur within a program or are external to the application and should be known. Events can be accepted or processed by Qobject subclasses, but are often used in components-related applications. In this paper, we mainly describe the event reception and processing in a typical application.

The delivery of the event is sent

When an event occurs, Qt represents it by instantiating an appropriate subclass of Qevent, which is then sent to the instance of Qobject (or its subclasses) by invoking the event () function.
The event () function itself does not handle events, depending on the event type, it invokes the appropriate event handler and returns whether the event is 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, and others from the application itself.

Type of Event

Most event types have specialized classes, such as Qresizeevent, Qpaintevent, Qmouseevent, Qkeyevent, and Qcloseevent. They are all qevent subclasses and add their own specific event handlers. For example, the Qresizeevent event adds the size () and oldsize () functions to make the component aware of its own size change.

Some events support more than one event type. For example, Qmouseevent mouse events, you can indicate the mouse press, double-click, move, and other actions.

Each event has its associated type, defined by Qevent::type. It is easy to use these types at runtime to determine which subclass of the event is.

Because of the diversity and complexity of the program response, the event delivery mechanism of Qt is flexible. The documentation for Qcoreapplication::notify () explains most of the content, and the articles in Qt quarterly another look at Events are also briefly described. Our exposition here is sufficient for the 95% program.

Handling of events

The processing of a typical event requires calling a virtual function. For example, the handling of the Qpaintevent event requires calling Qwidget::p the Aintevent () function. This virtual function is responsible for making the appropriate response, usually to redraw the component. If you do not intend to implement all the processing in your own function, you can call the implementation of the base class.
For example, the following code is used to manipulate the left mouse button to click on a custom selection box, while other click events are passed to the base class Qcheckbox processing.

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); }}
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

If you want to replace the processing of the base class, you must implement all the functions yourself. However, if you only want to extend the functionality of the sub-base class, you only need to implement the part you need, and the rest of the localize class will handle it for you.  
In rare cases, Qt may not specify a specialized handler function, or the specified handler function does not meet the requirements. This is usually the case with the TAB key processing. In general, the TAB key is used to move the focus, but some controls require the TAB key to do something else.  
These objects can be met by re-implementing Qobject::event (), which can either add their own processing before or after a generic processing call, or completely replace the event handler with its own event handler. A very rare control might have to handle both the TAB key and the program-specific event type. So, we can use the following code to implement.

bool mywidget::event (qevent *event) {if (event->type () = = qevent::keypress) {qkeyevent *ke = static_cast< ; Qkeyevent *> (event); if (ke->key () = = Qt::key_tab) {//special tab Handlin G here return true;} else if (event->type () = = Mycustomeventtype) { Mycustomevent *myevent = static_cast<mycustomevent *> (event); //Custom event handling here return true;} return qwidget::event (event);}           
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

Note that qwidget::event () is still called on those events that are not handled, and that the return value indicates whether the event is handled, and returns true to indicate that the event was blocked from being sent to another object.

Event filters

Sometimes, there is no specific event function, or there is insufficient functionality for a particular event. The most common example is pressing the TAB key. Under normal circumstances, it is qwidget to move the keyboard focus, but a few widgets need to be interpreted by themselves.
Let's try to imagine that we've got a Customerinfodialog widget. The Customerinfodialog contains a series of Qlineedit. Now, we want to use the SPACEBAR instead of tab to make the focus switch between these qlineedit.
A workaround is to subclass the Qlineedit, re-implement Keypressevent (), and Invoke Focusnextchild () in Keypressevent (). Like this:

void MyLineEdit::keyPressEvent(QKeyEvent *event) {      if (event->key() == Qt::Key_Space) { focusNextChild(); } else { QLineEdit::keyPressEvent(event); } }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

But there is one drawback. If there are many different controls (such as Qcombobox,qedit,qspinbox) in Customerinfodialog, we have to subclass so many controls. This is a cumbersome task.
A better solution is to allow Customerinfodialog to manage the key events of his child parts to achieve the required behavior. We can use event filters.

An event filter installation requires the following 2 steps:
1, call Installeventfilter () to register the objects that need to be managed.
2, in EventFilter () handles the event of the object that needs to be managed.

In general, it is recommended to register managed objects in the Customerinfodialog constructor. Like this:

CustomerInfoDialog::CustomerInfoDialog(QWidget *parent)    : QDialog(parent){     ...         firstNameEdit->installEventFilter(this);     lastNameEdit->installEventFilter(this);     cityEdit->installEventFilter(this);     phoneNumberEdit->installEventFilter(this);}
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

Once the event manager is registered, the event sent to Firstnameedit,lastnameedit,cityedit,phonenumberedit will first be sent to EventFilter ().

The following is an implementation of the EventFilter () function:

bool Customerinfodialog::eventfilter (Qobject *target, qevent *event) {if (target = = FirstNameE dit | | target = = Lastnameedit | | target = = Cityedit | |         target = = Phonenumberedit) {if (event->type () = = qevent::keypress)              {qkeyevent *keyevent = static_cast<qkeyevent *> (event); if (keyevent->key () = = Qt::key_space) {focusnextchild (); return true;} } return qdialog::eventfilter (target, event);}       
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

In the above function, we first check whether the target part is firstnameedit,lastnameedit,cityedit,phonenumberedit. Next, we determine whether the event is a key event. If the event is a keystroke event, we convert the event to qkeyevent. Next, we determine whether the spacebar is pressed, and if so, we call Focusnextchild () and pass the focus to the next control. Then, return, true to notify QT that we have handled the event.
If False is returned, QT continues to send the event to the target control, resulting in a space being inserted into the qlineedit.

If the target control is not qlineedit, or the key is not a spacebar, we will pass the event to the EventFilter () function of the base class.

QT provides 5 levels of event processing and filtering:
1, re-implement the event function. For example: Mousepressevent (), Keypress-event (), PaintEvent ().
This is the most common method of event handling.
2, re-implement Qobject::event ().
This is typically used when QT does not provide a handler function for the event. That is, when we add new events.
3, install event filter
4, install the event filter on the qapplication.
This is listed separately because the event filter on Qapplication captures all the events of the application, and the first one gets the event. That is, the event filter that is sent to qapplication before it is transmitted to any other event filter.
5, re-implement the Qapplication Notify () method.
QT uses notify () to distribute events. The only way to capture an event before any event handler captures an event is to re-implement the Qapplication Notify () method.

After QT creates the Qevent event object, it calls Qobject's event () function to distribute the event. Sometimes, you may need to do something else before calling the event () function, for example, some components on a dialog box may not need to respond to a carriage-down event, and you will need to redefine the component's event () function. If there are many components, you need to rewrite the event () function many times, which is obviously inefficient. To do this, you can use an event filter to determine if you need to invoke the event () function.

Qojbect has a eventfilter () function that is used to create an event filter. The signature of this function is as follows:

virtual BOOL Qobject::eventfilter (Qobject * watched, qevent * event)

If the watched object has an event filter installed, the function is called and the event is filtered before it is the turn of the component to handle the event. When overriding this function, if you need to filter out an event, such as stopping the response to the event, you need to return true

bool               Mainwindow::eventfilter (Qobject *obj, qevent *event) {if (obj = = textEdit) { if (event->type () = = qevent::keypress) {Qkeyevent *keyevent =                    static_cast (event);    Qdebug () << return true;    } else {return FALSE; }} else {//pass the event on to the parent class return qmainwindow::eventfilter (obj, event); }}               
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

In the example above, an event filter was created for MainWindow. To filter events on a component, you first need to determine which component of the object is, and then determine the type of the event. For example, I do not want the TextEdit component to handle keyboard events, so I first find this component, and if this event is a keyboard event, it returns true directly, that is, the event is filtered out, and the other events continue to be processed, so return false. For other components, we do not guarantee that there is a filter, so the safest way is to call the parent class function.

After creating the filter, the next thing to do is to install the filter. Installing the filter requires calling the Installeventfilter () function. The signature of this function is as follows:

void QObject::installEventFilter ( QObject * filterObj )
    • 1

This function is a function of qobject, so it can be installed to any qobject subclass, and not just the UI component. This function receives a Qobject object, and the component that invokes the function to install the event filter invokes the EventFilter () function defined by Filterobj. For example, Textfield.installeventfilter (obj), if an event is sent to the TextField component, the Obj->eventfilter () function is called First, and then Textfield.event () is called.

Of course, you can also install the event filter on top of qapplication so that you can filter all the events and gain greater control over them. However, the effect of this is to reduce the efficiency of the distribution of events.

If a component has more than one filter installed, the last one installed will be called first, similar to the behavior of the stack.

Note that if you delete a receive component in the event filter, be sure to set the return value to true. Otherwise, QT will distribute the event to the receiving component, causing the program to crash.

The event filter and the installed component must be on the same thread, otherwise, the filter does not work. Also, if the two components are on a different thread after the install, the filter will only be valid until they are back on the same thread.

The call to the event will eventually call Qcoreapplication's notify () function, so the maximum control is actually overriding the Qcoreapplication notify () function. As you can see, the event handling of QT is actually layered at five levels: Redefining event handlers, redefining the event () function, installing incident filters for a single component, installing event filters for Qapplication, redefining Qcoreapplication's Notify () Function. The control at these levels is increased by layer.

http://blog.csdn.net/u013007900/article/details/50074127

QT Learning Events and event filters (divided into five levels)

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.