QT Parent-child window event passing and event filter (some principles, more clearly)

Source: Internet
Author: User



When dealing with the monitoring system encountered problems, in the mainwidget to create a number of sub-widgets, the intention is to mouse click First let Mainwidget intercept processing and then assign to the child widget to deal with, but after debugging found if the child widget re-implement the event method, Just deal with the event directly, not into the Mainwidget processing method, if the child widget does not accept or ignore the event, then the event will be passed to its father, when the child widget exists an accept or ignore event, If you want to go through the process of mainwidget, you need to use the event handler, so look it up on the Internet and find that the QT event handler can handle it.



When Qt encapsulates an event as an qevent instance, it calls the Qobject event () method and transmits the Qevent instance to it, and in some cases, wants to process or filter some events before executing event () before deciding whether to call the event () method , you can use event filters at this time.



You can redefine the EventFilter () method of a class that inherits from Qobject (or its subclasses).



BOOL Filterobject::eventfilter (Qobject *object, qevent *event)



{



if (event->type () = = qevent::keypress)



{



Qkeyevent *keyevent = static_cast<qkeyevent *> (event);



if (keyevent->key () = = Qt::key_tab)



{



Handling the TAB key



return true;



}



}



return false;



}



The object parameter of EventFilter () indicates the source object where the event occurred, and EventFilter () returns false, the event () of the object on which it was installed will continue to execute and, if true, after the event filter object is installed () method is not executed, and the event interception is handled. To install an event filter for this object:



This->installeventfilter (this);






There are many types of QT events , and the common QT events are as follows :



Keyboard events: Press and release the key.



Mouse events: mouse movement, mouse button press and release.



Drag and Drop events: Drag and drop with the mouse.



Wheel event: Scroll the mouse wheel.



Paint Screen event: redraws Some parts of the screen.



Timed Event: Timer to time.



Focus Event: Keyboard focus movement.



Enter and leave an event: Move the mouse over the widget or move out.



Move event: Widget position changed.



Size Change Event: Widget size change.



Show and Hide events: Widgets Show and hide.



Window event: Whether the window is the current window.



There are also non-common QT events, such as socket events, clipboard events, font changes, layout changes, and so on.



QT events are not the same as signal in QT. The latter is often used to "use" widgets, while the former is used to "implement" widgets. For example a button, when we use this button, we only care about his clicked () of the signal, as for this button how to receive processing mouse events, and then launch this signal, we do not care. But if we're going to reload a button, we're going to face the event. For example, we can change its behavior, when the mouse button is pressed (mouse press event) triggers the signal of clicked () instead of the normally released (mouse release event).





The generation of events



Two sources of the event:



One is the system, usually the window system puts messages from the system, such as the mouse button, keyboard keys, etc., into the system's message queue. The QT event loop reads these events, transforms them into qevent, and then processes them in turn.



One is generated by the QT application program itself. The program generates events in two ways, one of which is to call Qapplication::p ostevent (). For example, the Qwidget::update () function, when the screen needs to be redrawn, the program calls the update () function, new comes out a paintevent, calls Qapplication::p ostevent (), puts it in the QT message queue, Wait to be processed sequentially. Another way is to call the Sendevent () function. The event is not placed in the queue, but is distributed and processed directly, as is the case with the Qwidget::repaint () function.






Scheduling of events


Two kinds of scheduling methods, one is synchronous, and the other is asynchronous.



The event loop for Qt is asynchronous, and when Qapplication::exec () is called, it enters the event loop. The loop can be simplified as described in the following code:



while (!app_exit_loop) {



while (!postedevents) {processpostedevents ()}



while (!qwsevnts) {qwsprocessevents (); }



while (!postedevents) {processpostedevents ()}



}



The events in the Qt event queue are processed first until they are empty. The message in the system message queue is processed until it is empty, and a new QT event is generated when the system message is processed and needs to be processed again.



When the qapplication::sendevent is called, the messages are processed immediately and are synchronized. In fact qapplication::sendevent () is directly into the dispatch and processing of the event by calling Qapplication::notify ().





Distribution and handling of events


First, the concept of event filter in Qt is explained. Event filters are a unique event-handling mechanism in QT that is powerful and flexible to use. It allows an object to listen for events that intercept another object. The event filter is implemented in this way: There is a member variable of type qobjectlist in the base class for all QT objects: Qobject, with the name Eventfilters, when one qobjec (Qobja) to another qobject (QOBJB) After the event filter is installed, QOBJB will save the Qobja pointer in Eventfilters. Before QOBJB handles an event, the Eventfilters list is checked first, and if not NULL, the EventFilter () function of the object in the list is called first. An object can install filters for multiple objects. Similarly, an object can be installed with multiple filters at the same time, and after the event arrives, these filters are called in reverse order of the installation order. The event filter function (EventFilter ()) return value is type bool, and if true, indicates that the event has been processed and QT will return directly for the next event to be processed; If False is returned, the event is then sent to the remaining event filter or target object for processing.



In Qt, the dispatch of events starts with Qapplication::notify (), since Qappliction is also inherited from Qobject, so check the Qappliation object first, and call these event filters first if there are event filters installed on the Qapp. Next Qapplication::notify () will filter or merge some events (such as the mouse events of the failed widget will be filtered out, while the same area of the repeating drawing events will be merged). After that, the event is sent to Reciver::event () processing.



Similarly, in Reciver::event (), first check if there is an event filter installed on the reciever. If so, call it. Next, depending on the type of qevent, the corresponding specific event handler is called. Some common events have specific event handlers, such as: Mousepressevent (), Focusoutevent (), Resizeevent (), PaintEvent (), Resizeevent (), and so on. In practical applications, it is often necessary to overload these specific event handlers in handling events. However, for those uncommon events, there is no specific event handler for the corresponding function. If you want to handle these events, you need to use a different method, such as overloading the event () function, or installing an incident filter.





Forwarding of events


  for certain categories of events ,  if the entire event has not been processed after the completion of the distribution process ,  Then this event will be forwarded up to its parent widget,  until the topmost window . ,  The event was first sent to qcheckbox,  if qcheckbox did not process ,  then by qgroupbox then process ,  if qgroupbox did not process   Sent to qdialog,  because qdialog is already the topmost widget,  So if qdialog does not process



How can I tell if an event has been handled? QT Neutralization Event-related functions communicate with each other in two ways . Qapplication::notify (), Qobject::eventfilter (), qobject::event () Indicates whether it has been processed by returning a bool value . "True " means that it has been processed , and "false " indicates that the event needs to continue passing . The other is to call Qevent::ignore () or qevent::accept () to identify the event . This method is used only for communication between the event () function and the specific event handler function . And only used in certain categories of events is meaningful , these events are mentioned above those will be forwarded events , including : Mouse , scroll wheel , buttons and other events .




Practical application





1. Overloading specific event handlers



The most common way to handle events is to overload specific event handlers such as Mousepressevent (), Keypressevent (), PaintEvent (). As an example of a key event, a typical processing function is as follows:



void Imageview::keypressevent (Qkeyevent * Event)



{



Switch (Event->key ()) {



Case Key_plus:



ZoomIn ();



Break



Case Key_minus:



Zoomout ();



Break



Case Key_left:



...



Default



Qwidget::keypressevent (event);



}



}



2. Reload the event () function




By overloading the event () function, we can process it before it is processed by a particular event handler (like Keypressevent ()). For example, this function is typically overloaded when we want to change the default action of the TAB key. Evnet () is also useful when dealing with some unusual events (such as Layoutdirectionchange), because these functions do not have a specific event handler function. When we reload the event () function, we need to call the event () function of the parent class to handle events that we do not need to deal with or do not know how to handle.



The following example shows how to reload the event () function to change the default action of the TAB key: (By default, the keyboard focus moves to the next control.)



BOOL Codeeditor::event (Qevent * Event)



{



if (event->type () = = qevent::keypress) {



Qkeyevent *keyevent = (qkeyevent *) event;



if (keyevent->key () = = Key_tab) {



Insertatcurrentposition (' \ t ');



return true;



}



}



Return Qwidget::event (event);



}




3. Install the event filter on the QT object



There are two steps to installing an event filter: (Suppose you want to use a to monitor the event of filter B)



First call the installeventfilter of B (const qoject *obj) with a pointer as the argument. All events destined for B will be processed first by the EventFilter () of a.



Then, a to overload the Qobject::eventfilter () function, write the code that handles the event in EventFilter ().



Use this method to rewrite the example above: (assuming we put codeeditor in Mainwidget)



Mainwidget::mainwidget ()



{



...



Codeeditor * CE = new Codeeditor (This, "Code Editor");



Ce->installeventfilter (this);



...



}



BOOL Mainwidget::eventfilter (Qoject * target, qevent * Event)



{



if (target = = CE) {



if (event->type () = = qevent::keypress) {



Qkeyevent *ke = (qkeyevent *) event;



if (ke->key () = = Key_tab) {



Ce->insertatcurrentposition (' \ t ');



return true;



}



}



}



return false;



}





4. Installing event filters for Qappliction objects


Once we put filters on Qapp (the only Qapplication object in each program ) , all events go through the current eventfilter () when they are sent to any other filter . This method is useful when debugging, and is often used to handle mouse events for failed widgets , usually qapplication::notify () . (In qapplication::notify () , the filter of Qapp is called First, and the event is parsed to determine whether to merge or discard )




5. Inherit the Qapplication class and overload the Notify () function



QT uses the qapplication::notify () function to distribute events . To get these events before any event filter can see any events , overloading the function is the only way . Usually the event filter is better used , Because there is no need to inherit the Qapplication class . And you can install any number of event filters for Qapplication objects , in contrast , the Notify () function has only one .



Http://www.cnblogs.com/bingcaihuang/archive/2010/12/17/1909369.html



QT Parent-child window event passing and event filter (some principles, more clearly)


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.