QT学习 (QEvent事件)

任何从QObject类派生的对象均可以通过QObject::event()方法接收事件;

事件产生时,QT会创建一个合适的QEvent对象或其子对象, 然后通过调用QObject类的event()函数将这个事件对象传给特定的QObject对象或其子对象

重新实现事件函数不需要调用, 因为在main.cpp中的exe()函数中有事件循环, 事件函数只是重新实现了一下, 事件函数时虚函数都在基类中定义的,在此处只是重新改写了函数内容.

事件处理顺序:

事件过滤器eventFilter(QObject *obj, QEvent *e);----->事件分发event(QEvent *e);-------->具体事件keyPressEvent(QKeyEvent *e)等事件

一. 事件处理方法

Qt的事件处理函数都是虚函数,在基类中声明,在子类中重新实现, 这些相应的事件函数在.h文件中定义在.cpp文件中重新实现函数内容

1. 重新实现特定事件

重新实现如 mousePressEvent()keyPressEvent()paintEvent() 等这些Qt事先已定义的事件处理器是进行事件处理的最简单的方式

2. 重新实现QObject::event()函数

通过重新实现event()函数, 可以在事件到达特定的事件处理器之前截获并处理它们. 这种方法可以用来覆盖已定义事件的默认处理方式,也可以用来处理Qt中尚未定义特定事件处理器的事件.当重新试下event()函数时, 如果不进行事件处理, 则需要调用基类的event()事件

3. 在QObject中注册事件过滤器

如果对象使用installEventFilter()函数注册了事件过滤器,目标对象中而所有事件将先发给这个监视对象的eventFilter()函数

4. 在QApplication中注册事件过滤器

如果一个事件过滤器被注册到程序中唯一的Qapplication对象,应用程序中的所有对象里的每一个事件都会在他们被送达其他事件过滤器前, 首先抵达这个eventFilter() 函数. 它可以用来处理一些通常被QApplication忽略的事件, 如发送给失效窗口的鼠标事件等.

5. 继承QApplication 并重新实现notify()函数

二. 具体实现

1. 键盘按下事件

//键盘按下事件
void Widget::keyPressEvent(QKeyEvent *ev)
{
    if(ev->key() == Qt::Key_F5)//F5按钮 
    {
    }
    if(ev->key() == Qt::Key_F1)//F1按钮 
    {
    }
}

头文件下把事件定义为 protected  类型 

2.  任意事件,该方法需要把 QEvent 转换为对应的事件类型;

        QEvent  *event;

     如: QEvent 转为QKeyEvent 类型: QKeyEvent *e = static_cast<QKeyEvent *>(event);

bool Widget::event(QEvent *event)
{
    if(event->type() == QEvent::KeyPress)  //键盘按下处理,其他事件让事件处理器自己处理,不能返回false
    {
        QKeyEvent *e = static_cast<QKeyEvent *>(event);//把QEvent类型转为QKeyEvent

        if(e->key() == Qt::Key_B) //如果是 键盘上的B键 将不会打印键值
        {
            return QWidget::event(event);
        }

        qDebug()<<(char)(e->key());
        return true;
    }
    else if(event->type() == QEvent::Timer)//计数器事件
    {
        //此处添加处理定时器事件的内容,如果想干掉定时器就直接返回true 定时器事件就不会处理
        QTimerEvent *ev = static_cast<QTimerEvent *>(event);//把QEvent类型转换为QTimerEvent
        timerEvent(ev);
        return true; //如果返回true,事件停止传播
    }
    else if(event->type() == QEvent::MouseMove)//鼠标移动事件  ,需要在构造函数中设置追踪鼠标
    {
        //鼠标移动处理事件,当返回true时就停止事件处理,所以在返回true前处理事件,打印坐标
        QMouseEvent *ev = static_cast<QMouseEvent *>(event);//把QEvent类型转换为QMouseEvent
        qDebug()<<QString("Mouse Move:(%1, %2)").arg(ev->x()).arg(ev->y());
        return true; //如果返回true,事件停止传播
    }
    else
    {
        return QWidget::event(event);
    }
}

其中QEvent包含QKeyEvent和QMouseEvent事件处理,在event中处理QKeyEvent事件将影响单独的QKeyEvent的事件处理函数

3. 事件过滤器

给某个控件 安装事件过滤器

给当前这个窗口安装事件过滤器

  (1). 安装某个对象下的事件过滤器   如:  ui->label->installEventFilter(this);//让父对象处理 安装当前对象下label这个控件的事件过滤器

  (2). 该方法需要把 QEvent 转换为对应的事件类型;通过事件过滤器处理事件

//事件过滤器
bool Widget::eventFilter(QObject *obj, QEvent *e)
{
   if(obj=this)
   {
       //类型转换 把 QEvent类型转换为QMouseEvent
       QMouseEvent *env = static_cast<QMouseEvent *>(e);
       //判断事件
       if(e->type()==QEvent::MouseMove)
       {
           qDebug()<<QString("Mouse ---- Move:%1 %2").arg(env->x()).arg(env->y());
           return true;//不让事件继续传播
       }
   }
   return QWidget::eventFilter(obj,e);//其他事件按照原来处理
}

在头文件定下各种事件

工程源码:https://download.csdn.net/download/dianzishi123/10918593

https://blog.csdn.net/tqs_1220/article/details/82534486

猜你喜欢

转载自blog.csdn.net/dianzishi123/article/details/85212268
今日推荐