A powerful function of the QT event model is that a qobject object can monitor the events that send other qobject objects and process the events before they arrive.
Suppose we have a customerinfodialog control consisting of some qlineedit controls. We want to use the space key to obtain the input focus of the next qlineedit. One of the most direct ways is to inherit from qlineedit and rewrite the keypressevent () function. When the Space key is clicked, call focusnextchild (): void mylineedit: keypressevent (qkeyevent * event) {If (Event-> key () = QT: key_space) {focusnextchild () ;}else {qlineedit: keypressevent (event );}} this method has the biggest drawback: If we use many different types of controls (qcombobox, qspinbox, and so on) in the form, we also need to inherit these controls, override their keypressevent (). A better solution is to enable customerinfodialog to monitor the Keyboard Events of its child controls and implement the above functions in the monitoring code. This is the method of event filtering. To implement an Event Filter, two steps are involved: 1. Call installeventfilter () on the target object to register the monitoring object. 2. Process events of the target object in the eventfilter () function of the Monitored object. The location of the registered monitoring object is in the merinfodialog constructor: mermerinfodialog (qwidget * parent): qdialog (parent ){... firstnameedit-> installeventfilter (this); lastnameedit-> installeventfilter (this); cityedit-> installeventfilter (this); phonenumberedit-> installeventfilter (this);} after the event filter is registered, events sent to the firstnameedit, lastnameedit, cityedit, and phonenumberedit controls first reach the customerinfodialog: eventfilter () function, and then reach the final destination. The code for the eventfilter () function is as follows: 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);} First, check whether the target control is qlineedit. If the event is a keyboard event, convert qevent to qkeyevent to determine the key to be hit. If it is the Space key, call focusnextchild () and hand the focus to the next control. Return true to notify QT that the event has been handled. If false is returned, QT will pass the event to the target control, insert a space character into qlineedit. If the target control is not qlineedit, or the event is not a space hit event, the control is handed over to the eventfilter () of the base class qdidit (). The target control can also be the control being monitored by the base class qdialog. (In qt4.1, qdialog has no monitoring controls, but other QT control classes, such as qscrollarea, monitor some of their child Controls) Qt event processing has 5 levels: 1. override the event processing functions of the control, such as rewriting keypressevent (), mousepressevent (), and paintevent (). This is the most common event processing method. We have seen many such examples. 2. Rewrite qobject: event () to process the event when it reaches the event processing function. This is done when you need to change the Regular usage of the tab key. You can also process rare event types that do not have specific event processing functions (for example, qevent: hoverenter ). When we override event (), we must call the event () of the base class to process the situations that we do not need to process by the base class. 3. Install the Event Filter for the qobject object: After the object uses installeventfilter (), all events that reach the target control first reach the eventfilter () function of the monitoring object. If an object has multiple event filters, the filters are activated in sequence, first to the recently installed monitoring object, and finally to the first installed monitoring object. 4. Install the Event Filter for qapplication. If the Event Filter is installed on qapp (the only qapplication object), all the object events in the program will be sent to the eventfilter () function. This method is very useful during debugging and is also frequently used when handling mouse events of inactive controls. 5. inherit from the qapplication and rewrite notify (). Qt calls qapplication: nofity () to send events. Override this function is the only way to get all events before other event filters process events. Generally, the event filter is the most useful, because at the same time, there can be any number of event filters, but the notify () function has only one. Many event types, including mouse and keyboard events, can be propagated. If an event arrives at the target object or is processed by the target object, the event processing starts again. The difference is that the target object is the parent control of the original target object. In this way, from the parent control to the parent control, you know that the control handles this event or reaches the top-level control. Figure 7.2 shows the propagation of a keyboard event from the Child control to the parent control in a dialog box. When a user clicks a keyboard, the time is first sent to the control with focus (qcheckbox in this example ). If qcheckbox does not process this event, QT sends the event to qgroupbox. If it still does not, it is finally sent to qdialog.
Figure 7.2. Event propagation in a dialog