QT Event Analysis

Source: Internet
Author: User
Tags message queue
Summary:

The QT program is event-driven, and each action of the program is triggered by an event behind the scenes.

The occurrence and processing of QT events becomes the main line of program operation, which exists in the whole life cycle of the program.

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.

The seminar is organized around the following three questions:

First, what is an event.

Second, how the incident was handled.

Three, the difference between the event and the signal.

first, what is an event.

Event: A message that is sent when an "action" is completed, and an object needs to be known. (personal view)

Explanation: At this time the "action" is not the usual meaning of the action, but the generalized "action", is the sum of active and passive.

Example: Two forms A and B, when a is minimized, we maximize it, which causes a to generate a redraw event, and when A and B are not minimized, and B is above the a form, we let B minimize, so a form that has just been masked by B will passively produce a redraw event.

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).

We divide events into two categories by Origin:

(a) system generated; Usually the window system puts the message from the system, such as the mouse button, keyboard keys, etc., into the system message queue, the QT event loop when reading these events, converted to qevent, and then processed in turn.

(b) is generated by the QT application program itself. There are two ways to generate events in a program, one 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. second, how the incident was handled. (a) Two scheduling methods, one is synchronous, and one 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 ().

(ii) Distribution and handling of incidents

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.

The flow chart for event distribution and processing is as follows:

(iii) forwarding of events

For certain categories of events, if the entire event has not been processed after the dispatch process, the event will be forwarded up to its parent widget until the topmost window. As the figure shows, the event is first sent to Qcheckbox, if Qcheckbox is not processed, then the qgroupbox is then processed, if the qgroupbox is not processed, and then sent to Qdialog, because Qdialog is already the top-level widget,       So if Qdialog is not processed, Qevent will stop forwarding. How can I tell if an event has been handled? Qt and event-related functions communicate with each other in two ways. Qapplication::notify (), Qobject::eventfilter (), Qobject::event () indicates whether or not 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 only used 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.

(iv) practical application

Based on the analysis of the QT event mechanism, we can get 5 levels of event filtering and processing methods. To function from weak to strong, arrange as follows:

(1) overload a specific event handler function.

The most common way to handle events is to overload specific event handlers such as Mousepressevent (), Keypressevent (), PaintEvent (). For example, a typical handler 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) Install the event filter to the Qappliction object.

Once we put a filter 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 very useful when debugging, and is often used to handle mouse events of defunct widgets, which are usually discarded by 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. In general, event filters are better used because there is no need to inherit the Qapplication class. And you can install any number of things to the Qapplication object.

Three, the difference between the event and the signal.

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).

Signals are implemented through events, events can be filtered, events are lower, events are basic, and signals are extended.

http://qimo601.iteye.com/blog/1407911

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.