• 第三十九课、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)、事件过滤器能够决定是否将事件转发到组件对象

  • 相关阅读:
    CSS 之 样式优先级机制
    SQL Server 之 修改时不允许保存更改
    IP_TOS选项
    eXosip2代码分析
    Ubuntu下关闭apache和mysql的开机启动
    linphone3.4.0代码分析
    XMPP/Jingle Vs SIP/SIMPLE 的简单介绍
    git命令常见问题总结
    正向代理与反向代理的区别
    SIP中OPTIONS方法的用法及示例
  • 原文地址:https://www.cnblogs.com/gui-lin/p/6415258.html
Copyright © 2020-2023  润新知