Qt学习之十五:事件总结

来源:互联网 发布:ip地址显示阿里云 编辑:程序博客网 时间:2024/06/09 21:19

Qt中的事件是整个 Qt 框架的核心机制之一,也比较复杂。说它复杂,更多是因为它涉及到的函数众多,而处理方法也很多,有时候让人难以选择。现在我们简单总结一下 Qt 中的事件机制。

Qt 中有很多种事件:鼠标事件、键盘事件、大小改变的事件、位置移动的事件等等。如何处理这些事件,实际有两种选择:
1. 所有事件对应一个事件处理函数, 在这个事件处理函数中用一个很大的分支语句进行选择,其代表作就是 win32 API 的 WndProc() 函数;
2、每一种事件对应一个事件处理函数。 Qt 就是使用的这么一种机制;Qt 具有这么多种事件处理函数,肯定有一个地方对其进行分发,否则, Qt 怎么知道哪一种事件调用哪一个事件处理函数呢?这个分发的函数,就是 event()。显然,当 QMouseEvent 产生之后, event() 函数将其分发给mouseEvent() 事件处理器进行处理。

现在我们可以总结一下 Qt 的事件处理,实际上是有五个层次:
1. 重写 paintEvent()、 mousePressEvent() 等事件处理函数。这是最普通、最简单的
形式,同时功能也最简单。
2. 重写 event() 函数。 event() 函数是所有对象的事件入口, QObject 和 QWidget
中的实现,默认是把事件传递给特定的事件处理函数。
3. 在特定对象上面安装事件过滤器。该过滤器仅过滤该对象接收到的事件。
4. 在 QCoreApplication::instance() 上面安装事件过滤器。该过滤器将过滤所有对象
的所有事件,因此和 notify() 函数一样强大,但是它更灵活,因为可以安装多个过滤
器。全局的事件过滤器可以看到 disabled 组件上面发出的鼠标事件。全局过滤器有
一个问题:只能用在主线程。
5. 重写 QCoreApplication::notify() 函数。这是最强大的,和全局事件过滤器一样提供完全控制,并且不受线程的限制。但是全局范围内只能有一个被使用(因为QCoreApplication 是单例的)。

事件处理机制实例:

#include "mainwindow.h"#include <QApplication>#include <QDebug>class Label:public QWidget{public:    Label()    {        installEventFilter(this);    }    bool eventFilter(QObject *watched, QEvent *event)    {        if(watched==this)        {            if(event->type()==QEvent::MouseButtonPress){                qDebug()<<"eventFilter";            }        }        return false;    }protected:    void mousePressEvent(QMouseEvent *)    {        qDebug()<<"MousePressEvent";    }    bool event(QEvent *e)    {        if(e->type()==QEvent::MouseButtonPress)        {            qDebug()<<"event";        }        return QWidget::event(e);    }};class EventFilter:public QObject{public:    EventFilter(QObject *watched,QObject *parent=0):QObject(parent),m_watched(watched)    {    }    bool eventFilter(QObject *watched, QEvent *event)    {        if(watched==m_watched)        {            if(event->type()==QEvent::MouseButtonPress)            {                qDebug()<<"QApplication::eventFilter";            }        }        return false;    }private:    QObject *m_watched;};int main(int argc, char *argv[]){    QApplication app(argc, argv);    Label label;    app.installEventFilter(new EventFilter(&label,&label));    label.show();    //MainWindow w;   // w.show();    return app.exec();}

运行结果:

这里写图片描述

从运行结果可以看出:全局事件过滤器首先被调用,然后是该对象上面的事件过滤器,其次是event函数,最后是特定的事件处理函数。

0 0
原创粉丝点击