QT Event Filter (Global filtering, easy)

Source: Internet
Author: User


A truly powerful feature of the QT event model is that an instance of Qobject can manage events for another Qobject instance.

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);
}
}

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

One Event Filters 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);
}
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 = = Firstnameedit | | 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);
}
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, installation Event Filters
4, Install on qapplication Event Filters
This is listed separately because: the qapplication on the Event FiltersAll events for the application are captured, and the event is first obtained. 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 an event filter is installed on the watched object, 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 this 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 () << "Ate Key Press" << Keyevent->key ();
return true;
} else {
return false;
}
} else {
Pass the event on to the parent class
return Qmainwindow::eventfilter (obj, event);
}
}





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)





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. It can be seen that the event processing of QT is actually layered five levels: Redefine event handler function, redefine events () function, install event filter for a single component, install event filter for Qapplication, Redefine Qcoreapplication's notify () function. The control at these levels is increased by layer.






About event handling See Also



Http://blog.csdn.net/xie376450483/archive/2010/08/18/5821970.aspx



Reference: http://blog.csdn.net/seanyxie/article/details/5930564



QT Event Filter (Global filtering, easy)


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.