第三十九课、Qt中的事件处理(下)------------------狄泰软件学院

一、Qt中事件处理的顺序

1、事件传递的过程

(1)、事件被组件对象处理后可能传递到其父组件对象

2、QEvent中的关键成员函数

#include "Widget.h"
#include <QEvent>
#include <QDebug>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
}

Widget::~Widget()
{
    
}
bool Widget::event(QEvent* e)
{
    if(e->type()==QEvent::KeyPress)
    {
        qDebug() << "Widget::event";
    }
    return QWidget::event(e);
}

void Widget::keyPressEvent(QKeyEvent* e)
{
    qDebug() << "Widget::keyPressEvent";//1.会先打印Widget::event再打印Widget::keyPressEvent
                                        //即先被事件总的事件函数处理,再在里面调用相应的事件处理函数

    QWidget::keyPressEvent(e);
}
实验一

实验二:

#ifndef MYEDIT_H
#define MYEDIT_H

#include <QLineEdit>

class MyEdit : public QLineEdit
{
    Q_OBJECT
public:
    bool event(QEvent* e);
    void keyPressEvent(QKeyEvent* e);
    explicit MyEdit(QWidget *parent = 0);
    
signals:
    
public slots:
    
};

#endif // MYEDIT_H
MyEdit.h
#include "MyEdit.h"
#include <QDebug>
#include <QEvent>
#include <QKeyEvent>
MyEdit::MyEdit(QWidget  *parent) :
    QLineEdit(parent)
{
}

bool MyEdit::event(QEvent* e)
{
    if(e->type()==QEvent::KeyPress)
    {
        qDebug() << "MyEdit::event";
    }

    return QLineEdit::event(e);
}
void MyEdit::keyPressEvent(QKeyEvent* e)
{
    qDebug() << "MyEdit::keyPressEvent";

    QLineEdit::keyPressEvent(e);

    //e->ignore();没有这句时只打印MyEdit::event和MyEdit::keyPressEvent,有这句时
    //打印 MyEdit::event和MyEdit::keyPressEvent、Widget::event和 Widget::keyPressEvent 说明可能传给父对象处理  

}
MyEdit.cpp
#ifndef WIDGET_H
#define WIDGET_H

#include <QtGui/QWidget>
#include "MyEdit.h"

class Widget : public QWidget
{
    Q_OBJECT
    MyEdit myEdit;

public:
    bool event(QEvent* e);
    void keyPressEvent(QKeyEvent* e);
    Widget(QWidget *parent = 0);
    ~Widget();
};

#endif // WIDGET_H
Widget.h
#include "Widget.h"
#include <QEvent>
#include <QDebug>


Widget::Widget(QWidget *parent)
    : QWidget(parent), myEdit(this)
{
}

Widget::~Widget()
{
    
}
bool Widget::event(QEvent* e)
{
    if(e->type()==QEvent::KeyPress)
    {
        qDebug() << "Widget::event";
    }
    return QWidget::event(e);
}

void Widget::keyPressEvent(QKeyEvent* e)
{
    qDebug() << "Widget::keyPressEvent";
                                        
    QWidget::keyPressEvent(e);


}
Widget.cpp
#include <QtGui/QApplication>
#include "Widget.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    
    return a.exec();
}
main.cpp

二、Qt事件的过滤器

1、Qt中的事件过滤器

(1)、事件过滤器可以对其它组件接收到的事件进行监控

(2)、任意的QObject对象都可以作为事件过滤器使用

(3)、事件过滤器对象需要重写evenFilter()函数

2、组件通过installEventFilter()函数安装事件过滤器

(1)、事件过滤器在组件之前接收到事件

(2)、事件过滤器能够决定是否将事件转发到组件对象

3、事件过滤器的典型实现

//1.判断是不是感兴趣的对象和事件
//2.若是,就决定是没收还是还是继续转发给感兴趣的对象
//3.若不是,就按默认的方式处理事件
//4.最后一定安装过滤器

bool Widget::eventFilter(QObject* obj, QEvent* e)
{
    bool ret = true;

    if(obj == &myEdit && (e->type() == QEvent::KeyPress))
    {
        qDebug() << "Widget::eventFilter";

                QKeyEvent* evt = dynamic_cast<QKeyEvent*>(e);

                switch(evt->key())
                {
                case Qt::Key_0://若按下0-9,则事件被传到文本框处理,输出,若不是,什么也不显示
                case Qt::Key_1:
                case Qt::Key_2:
                case Qt::Key_3:
                case Qt::Key_4:
                case Qt::Key_5:
                case Qt::Key_6:
                case Qt::Key_7:
                case Qt::Key_8:
                case Qt::Key_9:
                    ret = false;//如果是0-9,ret仍然是true,此时就会传递到感兴趣的对象
                    break;
                default:
                    break;
                }

    }
    else
    {
        ret = QWidget::eventFilter(obj, e);//如果不是感兴趣的事件或者对象,就按照默认方式处理
    }

    return ret;//返回true说明事件已被处理,返回false说明事件还未处理
}
重写事件过滤器函数

安装过滤器:

其它代码和上个例子一样

三、小结

(1)、Qt应用程序有严格的事件处理顺序

(2)、Qt事件在处理后可能传递给父组件对象

(3)、组件通过installEventFilter()函数安装事件过滤器

(4)、事件过滤器可以对其它组件接收到的事件进行监控

(5)、事件过滤器能够决定是否将事件转发到组件对象

原文地址:https://www.cnblogs.com/gui-lin/p/6415258.html