Qt 事件机制

QT事件机制

事件由用户的动作产生,通过操作系统传递到QApplication,再传递到发生动作相应的点如(Button),最后再触发该点上的信号,再传递到父类的消息机制。如图:


QEvent是所有事件类的基类,他提供了一些基础的事件方法
void accept (); //接收者处理当前事件
void ignore (); //接收者忽略当前事件,忽略后,事件可能传递给父组件
bool isAccepted(); //判断当前事件是否被处理过

静态函数 int registerEventType(int hint =-1) 提供自定义事件,创建一个唯一的事件编号

自定义事件

  • 继承QEvent。
  • 定义事件类型(取值在QEvent::User和QEvent::MaxUser之间,建议使用registerEventType()函数自动创建一个全局唯一一个的事件类型,防止重复)
    使用sendEvent()或postEvent()发送事件。
  • 需要在自定义类中重写
  • QObject::event()方法处理自定义事件。

myevent.h

#ifndef MYEVENT_H
#define MYEVENT_H
#include <QEvent>
class MyEvent : public QEvent
{
public:
    static const QEvent::Type type;
    MyEvent();
    ~MyEvent();
};
#endif // MYEVENT_H

myevent.cpp

#include "myevent.h"

MyEvent::MyEvent():QEvent(type){}
MyEvent::~MyEvent(){}
const QEvent::Type MyEvent::type = (QEvent::Type)MyEvent::registerEventType();

main

#include "widget.h"
#include <QApplication>
#include "qpushbutton.h"
#include "myevent.h"
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    QPushButton *btn = new QPushButton(&w);
    btn->setText("btn");
    QObject::connect(btn,&QPushButton::released,[&](void)->void{
        MyEvent *event = new MyEvent();
        QApplication::sendEvent(&w,event); //阻塞
 //QApplication::postEvent(&w,event,Qt::HighEventPriority); //异步 ,优先级
    });
    w.show();
    return a.exec();
}

重写窗口event函数

bool Widget::event(QEvent *event){
    if(event->type() == MyEvent::type){
        this->close();
    }
    QWidget::event(event);
}

事件过滤

  1. 通过void QObject::installEventFilter(QObject *filterObj) 函数安装过滤器
  2. 重写filterObj的bool QObject::eventFilter(QObject *watched, QEvent *event)函数
  bool MainWindow::eventFilter(QObject *obj, QEvent *event)
  {
      if (obj == textEdit) {
          if (event->type() == QEvent::KeyPress) {
              QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
              qDebug() << "Ate key press" << keyEvent->key();
              return true;
          } else {
              return false;
          }
      } else {
          // pass the event on to the parent class
          return QMainWindow::eventFilter(obj, event);
      }
  }
  1. 也可以通过QCoreApplication重写notify函数,实现一个总过滤
bool myApplication::notify(QObject *obj, QEvent *event)
{
    if(event->type() ==         QMouseEvent::MouseButtonPress)//可以设置此处的event->type()来捕获不同类型的event事件
    {
        qDebug()<<__PRETTY_FUNCTION__<<obj<<event;

    }
    else if(event->type() == QEvent::NonClientAreaMouseButtonRelease)
    {
        qDebug()<<__PRETTY_FUNCTION__<<obj<<event;//__FUNCTION__ 函数,提供类名和函数名称的输出
    }

    return QApplication::notify(obj,event);
}

在QCoreApplication::instance()上面安装事件过滤器。该过滤器将过滤所有对象的所有事件,但会有多线程问题。

一般情况下,通过重写相应的Event事件来进行事件过滤或操作。

Qt 事件机制

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动到顶部