第39课 Qt中的事件处理(下)

1、Qt中事件处理的顺序

    1.1、 事件传递的过程
        1.1.1、 事件被组件对象处理后可能(并不是一定)传递到其父组件对象
            
 
 1.2、QEvent中的关键成员函数
        

            实验一:
        MyEdit.h


#ifndef _MYEDIT_H_
#define _MYEDIT_H_
#include <QLineEdit>
#include <QDebug>
#include <QEvent>
#include <QKeyEvent>
class MyEdit : public QLineEdit
{
    Q_OBJECT
public:
    explicit MyEdit(QWidget *parent = 0);
    bool event(QEvent* e);           //这个QLineEdit也要实现消息处理函数。
    void keyPressEvent(QKeyEvent* e);
    
signals:
    
public slots:
    
};
#endif // QLINEEDIT_H


MyEdit.cpp实现文件

#include "MyEdit.h"
MyEdit::MyEdit(QWidget *parent) :
    QLineEdit(parent)
{
}
bool MyEdit::event(QEvent* e)           //这个QLineEdit也要实现消息处理函数。
{
    if(e->type() == QEvent::KeyPress)
    {
        qDebug() << "bool MyEdit::event(QEvent* e) ";
    }
    return QLineEdit::event(e);
}
void MyEdit::keyPressEvent(QKeyEvent* e)
{
    qDebug() << "MyEdit::keyPressEvent(QKeyEvent* e)";
    QLineEdit::keyPressEvent(e);
    //e->ignore();//没有这句时只打印MyEdit::event和MyEdit::keyPressEvent,有这句时打印 MyEdit::event和MyEdit::keyPressEvent、Widget::event和 Widget::keyPressEvent 说明可能传给父对象处理
}

Widget.h头文件

#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.cpp实现文件

#include "Widget.h"
#include <QEvent>
#include <QKeyEvent>
#include <QDebug>
Widget::Widget(QWidget *parent)
    : QWidget(parent), myEdit(this)
{
}
Widget::~Widget()
{
}
bool Widget::event(QEvent *e)   //重写总的事件处理函数。
{
    //qDebug() << e->type();
    if(e->type() == QEvent::KeyPress)
    {
        qDebug() << "Widget::event";
    }
    return QWidget::event(e);   //返回是否执行成功?
}
void Widget::keyPressEvent(QKeyEvent *e)   //按键点击的具体事件。
{
    qDebug() << "Widget::keyPressEvent(QKeyEvent *e)";//1、会先打印widget::event再打印Widget::keyPressEvent,即先被总的事件函数处理,然后调用相应具体的事件处理函数。
    QWidget::keyPressEvent(e);
}

main.cpp实现文件。

#include <QtGui/QApplication>
#include "Widget.h"
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    
    return a.exec();
}


2、Qt事件的过滤器

    2.1、 Qt中的事件过滤器
        2.1.1、 事件过滤器可以对其它组件接收到的事件进行监控
        2.1.2、 任意的QObject对象都可以作为事件过滤器使用
        2.1.3、 事件过滤器对象需要重写evenFilter()函数

    2.2、 组件通过installEventFilter()函数安装事件过滤器
        2.2.1、 事件过滤器在组件之前接收到事件
        2.2.2、 事件过滤器能够决定是否将事件转发到组件对象
                    
    2.3、事件过滤器的典型实现
            
                                  

    2.4、添加过滤器的实现代码。

//1、判断是不是感兴趣的对象和事件
//2、若是,就决定是没收还是继续转发给感兴趣的对象
//3、若不是,就按默认的方式处理事件
//4、最后一定安装时间过滤器。
bool Widget::eventFilter(QObject *obj, QEvent *e)
{
    bool ret = true;
    if(obj == &myEdit && (e->type() == QEvent::KeyPress))
    {
        qDebug() << "Widget::eventFilter(QObject *obj, QEvent *e)";
        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说明事件还未处理。
}


!!!必须有的安装过滤器代码。    其他代码和上个例子一样。



3、小结

    3.1、 Qt应用程序有严格的事件处理顺序
    3.2、 Qt事件在处理后可能传递给父组件对象
    3.3、 组件通过installEventFilter()函数安装事件过滤器
    3.4、 事件过滤器可以对其它组件接收到的事件进行监控
    3.5、 事件过滤器能够决定是否将事件转发到组件对象


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值