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);
}
事件过滤
- 通过
void QObject::installEventFilter(QObject *filterObj)
函数安装过滤器 - 重写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);
}
}
- 也可以通过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 事件机制