Events in Qt (2) - Event Filters

In the previous article, we introduced Qt's events and the order of event delivery. Before the object processes the event, it will go through the object filter to determine whether the event is delivered to the object. In this chapter we will introduce event filters for Qt objects.
Link to the previous article:
Events in Qt (1)

Event filters, which can handle or dispatch specific events.
① If Qt does not provide a specific virtual function for an event, we can use an event filter to handle the event.
② The event can be processed before the event is passed to an object, and a judgment is made whether the event is passed to the object.

The event filter must be a class inherited from QObject or a class derived from QObject, and receive event processing by overriding the eventFilter method of the QObject class. The prototype of the eventFilter function is as follows:
virtual bool eventFilter(QObject *watched, QEvent *event);
Parameters: watched is the monitored object, and event is the event
Return value: Indicates whether the event is filtered. true, means that the event is not delivered to the watched, and false means that it is delivered to the watched object.

The monitored object needs to install its object monitor, use the following function to install
void installEventFilter(QObject *);

The following is an example of an event filter, the code in the previous chapter of this chapter, the added code will be highlighted below:
Contents of the .h file:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QPushButton>

class PushButton : public QPushButton
{
    Q_OBJECT

public:
    PushButton(QWidget *parent = nullptr);
    ~PushButton();

protected:
    virtual void mousePressEvent(QMouseEvent *event);
};

// -----------------------------------------------------------------------------------
class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = 0);
    ~Widget();

protected:
    virtual void mousePressEvent(QMouseEvent *event);


private:
    QPushButton *m_Button = nullptr;
};

// -----------------------------------------------------------------------------------
class EventWatcher : public QObject
{
    Q_OBJECT

public:
    EventWatcher(QObject *parent = nullptr);
    ~EventWatcher();

protected:
    virtual bool eventFilter(QObject *obj, QEvent *event);
};

#endif // WIDGET_H

Content in .cp:

#include "widget.h"
#include <QVBoxLayout>
#include <QDebug>
#include <QMouseEvent>

PushButton::PushButton(QWidget *parent)
    :QPushButton(parent)
{
    this->setFixedSize(200, 200);
}

PushButton::~PushButton()
{

}

void PushButton::mousePressEvent(QMouseEvent *event)
{
    QPushButton::mousePressEvent(event);
    qDebug() << "MousePressed " << event->pos().x() << ", " << event->pos().y();
    event->ignore();
}

// -----------------------------------------------------------------------------------
Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    m_Button = new PushButton(this);
    m_Button->setText("OK");

    // 安装过滤器
    EventWatcher *watcher = new EventWatcher(this);
    m_Button->installEventFilter(watcher);

    QVBoxLayout *layout = new QVBoxLayout(this);
    layout->addWidget(m_Button);

    QObject::connect(m_Button, &QPushButton::clicked, [=](void)->void{
       qDebug() << "PushButton Pressed!" ;
    });

    this->setGeometry(100, 100, 800, 600);
}

Widget::~Widget()
{

}

void Widget::mousePressEvent(QMouseEvent *event)
{
    int xPt = event->pos().x();
    int yPt = event->pos().y();
    qDebug() << "QWidget " << xPt << ", " << yPt;
    return QWidget::mousePressEvent(event);
}

// -----------------------------------------------------------------------------------
EventWatcher::EventWatcher(QObject *parent)
    :QObject(parent)
{

}

EventWatcher::~EventWatcher()
{

}

bool EventWatcher::eventFilter(QObject *obj, QEvent *event)
{
    if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonDblClick)
    {
        return true;
    }

    return QObject::eventFilter(obj, event);
}

Starting from line 37 of the header file, a class of monitor is added. In line 32 of the source file, the event filter is added to the button object;
the click and double-click events of the button are monitored and are not passed to the button object, so The running effect of the program is that there is no response when the button is clicked.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325588473&siteId=291194637