1.2.1 Qt中事件是如何进行传递——实例篇(下)

1.2.1 Qt中事件是如何进行传递

1.2.2 Qt中的事件过滤器(eventFilter)

1.2.3 如何自己模拟发送事件消息

一、Qt中事件是如何进行传递-代码篇

上一篇中我们讲解了Qt中的事件,通过流程图给大家展示了事件的传递过程,今天就通过代码来给大家实操一下,验证流程图的走向。

EventTestWgt.h

#ifndef _EVENT_TEST_WGT_H
#define _EVENT_TEST_WGT_H

#include 
#include 

class MyApplication : public QApplication
{
public:
	MyApplication(int &argc, char **argv);

	bool notify(QObject *receiver, QEvent *e);
};

// 事件过滤器对象;
class EventFilterObj : public QObject
{
public:
	EventFilterObj(QObject* parent = nullptr);

private:
	bool eventFilter(QObject *watched, QEvent *event);

};

class EventTestWgt : public QWidget
{
	Q_OBJECT

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

private:
	void mousePressEvent(QMouseEvent *event);

private:
	bool event(QEvent* ev);
	bool eventFilter(QObject *watched, QEvent *event);

private:
	EventFilterObj* m_eFilterObj;
};
#endif // _EVENT_TEST_WGT_H

EventTestWgt.cpp

#include "EventTestWgt.h"
#include 
#include 
#include 

MyApplication::MyApplication(int &argc, char **argv)
	: QApplication(argc, argv)
{
}

bool MyApplication::notify(QObject *receiver, QEvent *e)
{
   	if (QEvent::MouseButtonPress == e->type()) {
        qDebug() << "MyApplication::notify - " << "Class Name:" << receiver->metaObject()->className()
        	<< "Event:" << e->type();
	}
    
    // 这里一定要返回父类的函数,要不然事件没法继续传递;
    return QApplication::notify(receiver, e);
}

EventFilterObj::EventFilterObj(QObject* parent /*= nullptr*/)
	: QObject(parent)
{
}

bool EventFilterObj::eventFilter(QObject *watched, QEvent *event)
{
    if (QEvent::MouseButtonPress == event->type())
    {
        qDebug() << "EventFilterObj::eventFilter"
        << "Class Name:" << watched->metaObject()->className()
        << "Event:" << event->type();
    }
    
    return QObject::eventFilter(watched, event);
}

EventTestWgt::EventTestWgt(QWidget *parent)
	: QWidget(parent)
{
    // 创建事件过滤器对象;
    m_eFilterObj = new EventFilterObj(this);
    
    // 给自己安装事件过滤器;
    this->installEventFilter(this);
    // 安装外部事件过滤器;
    this->installEventFilter(m_eFilterObj);
    
    this->resize(300, 200);
}

EventTestWgt::~EventTestWgt()
{
}

void EventTestWgt::mousePressEvent(QMouseEvent *event)
{
    qDebug() << "EventTestWgt::mousePressEvent";
    
    return QWidget::mousePressEvent(event);
}

bool EventTestWgt::eventFilter(QObject *watched, QEvent *event)
{
    if (watched == this){
        if (QEvent::MouseButtonPress == event->type())
        {
            qDebug() << "EventTestWgt::eventFilter - "
            	<< "Class Name:" << watched->metaObject()->className()
            	<< "Event:" << event->type();
        }
	}
    
    return QWidget::eventFilter(watched, event);
}

bool EventTestWgt::event(QEvent* ev)
{
    if (QEvent::MouseButtonPress == ev->type()){
        qDebug() << "EventTestWgt::event - MouseButtonPress";
    }
    
    // 其他事件使用父类的方法继续进行传递处理;
    return QWidget::event(ev);
}

int main(int argc, char *argv[])
{
    // 这个一定要用重写的MyApplication类;
    MyApplication a(argc, argv);
    
    EventTestWgt wgt;
    wgt.show();
    
    return a.exec();
}

图一:事件传递流程图

1.2.1 Qt中事件是如何进行传递——实例篇(下)_第1张图片

在上面的例子中我们做了这几件事来监测鼠标按下事件:

  1. 我们继承了QApplication,重写了notify方法;
  2. 新建了事件过滤器类EventFilterObj;
  3. EventTestWgt类中添加了自己的事件过滤器(即对象可以给本身安装事件过滤器);
  4. EventTestWgt类中重写了event方法;
  5. EventTestWgt类中重写了mousePressEvent方法;

关于事件过滤器,这里我们新建了一个专门的事件过滤器类来进行验证,也可以自己重写自己本身的事件过滤器然后给自己安装上,这样就是自己监测自己了,本篇主要验证事件的传递流程,事件过滤器在下篇文章中再详细说明。
我们可以对照着上方图一的事件传递流程图,然后下方图二这个空白的窗口就是运行界面,然后我们鼠标点击一下这个界面,就有了图三的编译器中打印的信息。

图二:程序实际运行图

1.2.1 Qt中事件是如何进行传递——实例篇(下)_第2张图片

图三:程序运行结果输出图

1.2.1 Qt中事件是如何进行传递——实例篇(下)_第3张图片


从图三的打印信息中,我们看到上方代码的运行结果,验证Qt中事件实际传递的顺序如下:

1.2.1 Qt中事件是如何进行传递——实例篇(下)_第4张图片

建议大家使用示例代码自己再改一改测试一下其他的事件,或者再结合一些实例去解决一些问题,我们在了解到Qt事件的传递机制之后,这样更方便我们在实际应用中想到在哪个流程去更准确地过滤或者去处理一些相应的事件,而不会影响其他控件接收事件,或者继续传递等问题。

你可能感兴趣的:(Qt基础内容教程,qt,事件,event,eventFilter)