Accept, ignore, and redefine event filters for event qevents

Source: Internet
Author: User

Event handling process:
An event occurs ------> exec () loop will receive this event ------>

Create an event object and pass it to QObject: event () ------>

In the QWidget: event () function, assign a specific event handler ------>

Emit (clicked message) in the QButton event processing function)

The role of the event is described above. Let's take a look at how we can receive the event. Recall the previous code. We have rewritten the event function in the subclass so that these subclasses can complete some functions as needed, just like the following code:

Void MyLabel: mousePressEvent (QMouseEvent * event)
{
If (event-> button () = Qt: LeftButton ){
// Do something
} Else {
QLabel: mousePressEvent (event );
}
}

The code above is similar to the previous one. It is detected in the mouse-pressed event. If you press the left button to do our processing work, if it is not the left button, the function of the parent class is called. To some extent, the event is passed to the parent class for response. That is to say, the event is "ignored" in the subclass.

We can regard Qt event transmission as a chain: If the subclass does not process this event, it will continue to pass to other classes. In fact, Qt event objects all have an accept () function and ignore () function. Just like their names, the former is used to tell Qt that the event processing function "receives" the event and does not pass it any more. The latter tells Qt that the event processing function "ignores" the event, you need to continue the transfer and find another recipient. In the event processing function, you can use isAccepted () to check whether the event has been received.

In fact, we seldom use the accept () and ignore () functions. Instead, we just want to call the response function of the parent class if we want to ignore the event. As we once said, most events in Qt are protected. Therefore, the rewritten function must have a response function in its parent class. This method is feasible. Why? Because we cannot confirm that this handler function in the parent class has no operation, if we ignore the event directly in the subclass, Qt will not look for other recipients, then the operation of the parent class will not be performed, this may cause potential risks. In addition, let's take a look at the implementation of the QWidget's mousePressEvent () function:

Void QWidget: mousePressEvent (QMouseEvent * event)
{
Event-> ignore ();
If (windowType () = Qt: Popup )){
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 will be ignored if all subclasses do not overwrite the mousePressEvent function. This implies that this component does not care about this event, this event may be passed to its parent component.

However, things are not absolute. In one case, we must use the accept () and ignore () functions, that is, when the window is closed. If you need a dialog box when the window is closed, you need to write it as follows:

Void MainWindow: closeEvent (QCloseEvent * event)
{
If (continueToClose ()){
Event-> accept ();
} Else {
Event-> ignore ();
}
}

Bool MainWindow: continueToClose ()
{
If (QMessageBox: question (this,
Tr ("Quit "),
Tr ("Are you sure to quit this application? "),
QMessageBox: Yes | QMessageBox: No,
QMessageBox: No)
= QMessageBox: Yes ){
Return true;
} Else {
Return false;
}
}

In this way, we can exit the program after inquiry.

Today we are talking about the event () function. I have mentioned this function before, saying that after the event object is created, Qt will pass this event object to the event () function of QObject. The event () function does not directly process events, but distributes these event objects to different event handlers according to their types ).

The event () function is mainly used for event distribution. Therefore, if you want to perform some operations before event distribution, you need to pay attention to this event () function. To achieve 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, rather than the focus component, You can inherit the QWidget, and rewrite its event () function to achieve this goal:

Bool MyWidget: event (QEvent * event ){
If (event-> type () = QEvent: KeyPress ){
QKeyEvent * keyEvent = static_cast <QKeyEvent *> (event );
If (keyEvent-> key () = Qt: Key_Tab ){
// Process the Tab worker
Return true;
}
}

Return QWidget: event (event );
}

The event () function accepts a QEvent object, that is, the object that requires this function to forward. In order to forward data, a series of type judgments are required. Therefore, you can call the Type () function of QEvent. The returned value is the QEvent: type enumeration. After processing the events we need, we can return them directly. For other events we don't care about, we need to call the event () function of the parent class to continue forwarding, otherwise, this component can only process the events we define.

The Return Value of the event () function is of the bool type. If the input event is recognized and processed, true is returned. Otherwise, false is returned. If the returned value is true, QApplication considers that the event has been processed and continues to process the next event in the event queue. If the returned value is false, QApplication tries to find the next processing function of the event.

The Return Value of the event () function is different from the accept () and ignore () Functions of the event. The accept () and ignore () functions are used for communication between different event processors, for example, to determine whether the event is processed. The return value of the event () function is mainly to notify QApplication of notify () whether the function processes the next event. To clarify this, let's take a look at how the QWidget event () function 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 distribute it to different event handlers. After the event processing function, use the isaccepted () method of the event to check whether the event is accepted. If the event is not accepted, the event () function returns false immediately; otherwise, the system returns true.

Another scenario where the event () function must be rewritten is when a custom event exists. If your program contains custom events, you must rewrite the event () function to distribute custom events. Otherwise, your custom events will never be called.

Create event filters and install event Filters

After QT creates a qevent event object, it calls the qobject event () function for event distribution. Sometimes, you may need to do some other operations before calling the event () function. For example, some components in the dialog box may not need to respond to the event of press Enter. At this time, you need to redefine the event () function of the component. If there are many components, You need to rewrite the event () function many times, which is obviously inefficient. Therefore, you can use an Event Filter to determine whether to call the event () function.

Qojbect has an eventfilter () function used to create an Event Filter. The signature of this function is as follows:

Virtual bool qobject: eventfilter (qobject * watched, qevent * event)

If the event filter is installed on the watched object, this function will be called and used for Event Filtering before the component can process the event. When rewriting 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 <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 above example, an event filter is created for mainwindow. To filter events on a component, you must first determine which component the object is and then determine the type of the event. For example, if I don't want the textedit component to handle keyboard events, I first find this component. If this event is a keyboard event, true is returned directly, that is, the event is filtered out, other events still need to be processed, so false is returned. For other components, we do not guarantee whether there is a filter, so the safest way is to call the function of the parent class.

After a filter is created, install the filter. To install the filter, you must call 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, not just the UI component. This function receives a QObject object. components that call this function to install the Event Filter will call the eventFilter () function defined by filterObj. For example, in textField. installEventFilter (obj), if an event is sent to the textField component, the obj-> eventFilter () function is called before textField. event () is called ().

Of course, you can also install the Event Filter on QApplication to filter all events and gain greater control. However, the consequence of doing so is to reduce the efficiency of event distribution.

If a component is installed with multiple filters, the last installed filter is called first, similar to the stack action.

Note: If you delete a receiving component in the Event Filter, you must set the return value to true. Otherwise, Qt will still distribute the event to the receiving component, resulting in program crash.

The Event Filter and installed components must be in the same thread. Otherwise, the filter does not work. In addition, if the two components arrive at different threads after the install, the filter will be valid only when the two return to the same thread.

The call of the event will eventually call the notify () function of QCoreApplication. Therefore, the maximum control is actually to override the notify () function of QCoreApplication. It can be seen that Qt event processing is actually divided into five layers: redefinition of event processing functions, redefinition of event () functions, and installation of event filters for a single component, install the Event Filter for QApplication and redefine the notify () function of QCoreApplication. The control of these layers is increased layer by layer.

See

Http://blog.csdn.net/xie376450483/archive/2010/10/09/5930564.aspx

 

This article from the CSDN blog, reproduced please indicate the source: http://blog.csdn.net/xie376450483/archive/2010/08/18/5821970.aspx

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.