Reprint Source: http://blog.csdn.net/seanyxie/article/details/5821970
Event Processing Flow:
An event occurs------the >exec () loop receives the event------>
Creates an event object and passes the object to Qobject::event ()------>
In the Qwidget::event () function, assign to a specific event handler------>
Emit (clicked message) in the event handler function of Qbutton
Before we talk about the role of events, let's look at how we can receive events. Recalling the previous code, we overridden the event function in the subclass to allow these subclasses to do what we need, just like the following code:
void Mylabel::mousepressevent (Qmouseevent * Event)
{
if (Event->button () = = Qt::leftbutton) {
Do something
} else {
Qlabel::mousepressevent (event);
}
}
The above code is similar to the previous, detected in the mouse down event, if the left button is pressed, do our work, if not left, then call the parent class function. This, in a way, is to pass the event up to the parent class to respond, i.e. we "ignore" the event in the subclass.
We can think of the Qt event pass as a chain: if the subclass does not handle the event, it will continue to pass to the other classes. In fact, the event object for Qt has an accept () function and a ignore () function. As their name says, the former is used to tell Qt that the event handler "receives" the event and does not pass it, while the latter tells Qt that the event handler "ignores" the event and needs to continue passing to find another recipient. In the event handler function, you can use isaccepted () to query whether the event has been received.
In fact, we seldom use the accept () and ignore () functions, but like the example above, if you want to ignore the event, just call the parent class's response function. Remember we once said that the events in Qt are mostly protected, so that the overridden function must have a response function in its parent class, and this method is feasible. Why did you do it? Because we cannot confirm that this handler function in the parent class has no action, if we ignore the event directly in the subclass, QT will not look for other recipients, then the parent class will not be able to do so, which can potentially be dangerous. Also, let's look at the implementation of Qwidget's Mousepressevent () function:
void Qwidget::mousepressevent (Qmouseevent *event)
{
Event->ignore ();
if ((windowtype () = = Qt::P opup)) {
Event->accept ();
qwidget* W;
while (w = qapp->activepopupwidget ()) && W! = this) {
W->close ();
if (qapp->activepopupwidget () = = W)//widget does not want to dissappear
W->hide (); Hide at least
}
if (!rect (). Contains (Event->pos ())) {
Close ();
}
}
}
Note that the first statement, if all subclasses do not overwrite the Mousepressevent function, is ignored here, suggesting that the component does not care about the event, which could be passed to its parent component.
However, things are not absolute. In one case, we have to use the accept () and ignore () functions, that is, when the window is closed. If you need to have a query dialog when the window is closed, you need to write this:
void Mainwindow::closeevent (Qcloseevent * Event)
{
if (Continuetoclose ()) {
Event->accept ();
} else {
Event->ignore ();
}
}
BOOL Mainwindow::continuetoclose ()
{
if (Qmessagebox::question (this,
TR ("Quit"),
TR ("is sure to quit this application?"),
Qmessagebox::yes | Qmessagebox::no,
Qmessagebox::no)
= = Qmessagebox::yes) {
return true;
} else {
return false;
}
}
This way, we will not be able to exit the program until we ask.
The event () function is to be said today. Remember that this function has been mentioned before, saying that after the event object is created, QT passes the event object to the Qobject () function. The event () function does not directly handle events, but instead distributes these event objects to different event handlers according to their different types (handler).
The event () function is primarily used for distribution of events, so if you want to do something before the event is distributed, you need to be aware of the event () function. For this purpose, we can rewrite the event () function. For example, if you want to move the focus to the next component when the TAB key in the window is pressed, instead of letting the focused component handle it, you can inherit the Qwidget and rewrite its event () function to do this:
BOOL Mywidget::event (qevent *event) {
if (event->type () = = qevent::keypress) {
Qkeyevent *keyevent = static_cast<qkeyevent *> (event);
if (keyevent->key () = = Qt::key_tab) {
Handling tab Keys
return true;
}
}
Return Qwidget::event (event);
}
The event () function accepts an Qevent object, which is the object that needs to be forwarded by this function. In order to forward, it is necessary to have a series of type judgments, which can call Qevent's type () function, whose return value is an enumeration of the Qevent::type type. After we have dealt with the events we need, we can return directly, and for other events that we do not care about, we need to call the parent class's event () function to continue forwarding, otherwise this component will only be able to handle the events we have defined.
The event () function return value is type bool, which returns TRUE if the incoming event has been recognized and processed, otherwise false. If the return value is True,qapplication, the event is considered to have been processed, the next event in the event queue will continue to be processed, and if the return value is false,qapplication, it will attempt to find the next handler for the event.
The return value of the event () function is different from the accept () and ignore () functions for events. The Accept () and ignore () functions are used for communication between different event handlers, such as determining whether the event is handled; the return value of the event () function is primarily to inform Qapplication that the Notify () function handles the next event. To make this clearer, let's look at how the event () function of qwidget is defined:
BOOL Qwidget::event (qevent *event) {
Switch (E->type ()) {
Case Qevent::keypress:
Keypressevent ((Qkeyevent *) event);
if (! ( (Qkeyevent *) event)->isaccepted ())
return false;
Break
Case Qevent::keyrelease:
Keyreleaseevent ((Qkeyevent *) event);
if (! ( (Qkeyevent *) event)->isaccepted ())
return false;
Break
More ...
}
return true;
}
The event () function of Qwidget uses a huge switch to determine the type of qevent and distributes it to different event handlers. After the event handler, use the Isaccepted () method of the event to know that the event is not accepted, and if it is not accepted, the event () function immediately returns FALSE, otherwise it returns true.
Another case where the event () function must be rewritten is when there are custom events. If you have custom events in your program, you must override the event () function to distribute custom events, or your custom events will never be called.
Create event filters and install event filters
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 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<qkeyevent*> (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. 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.
See
Http://blog.csdn.net/xie376450483/archive/2010/10/09/5930564.aspx
Event Qevent accept and ignore and redefine event filters (GO)