首先要明白一个概念,事件和信号并不一样,比如单击一下鼠标,就会产生鼠标事件(QMouseEvent),是对这个动作的描述,而因为按钮被按下了,按钮会发出clicked()的单击信号(是按钮控件产生的)。
1.事件处理方式:
method 1:重新实现部件的事件处理函数,如:mousePressEvent(),keyPressEvent()等等。是最常用的方法!!!
method 2:重新实现notify()函数。需要继承QApplication类,可以再事件过滤事件之前获得事件,一次只可以处理一个事件。
method 3:向QApplication的全局对象安装时间过滤器,一个程序只有一个QApplication对象,可以处理多个事件,与method 2功能相同。
method 4:重新实现event()函数。QObject的event()函数可以再默认事件处理函数之前获得该事件。
method 5:在对象上安装事件过滤器。
2.事件传递过程:
父部件的事件过滤器 -> 本部件的event()函数 -> 本部件的事件处理函数 -> 父部件的处理函数(前提是子部件忽略该事件)
父部件的代码示例(分别为.h和.cpp):
public:
bool eventFilter(QObject *obj, QEvent *event);
protected:
void keyPressEvent(QKeyEvent *event);
bool Widget::eventFilter(QObject *obj, QEvent *event)
{
if(obj == lineEidt)
{
if(event->type() == QEvent::KeyPress)
qDebug() << "widget的事件过滤器";
}
return QWidget::eventFilter(obj,event);
}
void Widget::keyPressEvent(QKeyEvent *event)
{
qDebug() << "widget键盘按下事件";
}
子部件的代码实例:(QLineEdit控件)
public:
bool event(QEvent *event);
protected:
void keyPressEvent(QKeyEvent *event);
bool MyLineEdit::event(QEvent *event)
{
if(event->type() == QEvent::KeyPress)
{
qDebug() << "MyLineEdit的event()函数";
event->ignore();
return true;
}
return QLineEdit::event(event);
}
void MyLineEdit::keyPressEvent(QKeyEvent *event)
{
qDebug() << "MyLineEdit键盘按下事件";
QLineEdit::keyPressEvent(event);
event->ignore();
}
运行结果如下:(如果在子部件没有忽略事件,那么父部件的事件处理函数不会被调用)
3.事件过滤器:
只是QObject 的两个函数:
installEventFilter();安装事件过滤器
eventFilter(QObject *obj, QEvent *event);实现事件处理
4.事件发送:
QApplication类的sendEvent()和postEvent();
区别:
postEvent | sendEvent |
放到等待调度队列 | 立即处理 |
必须在堆上(new)创建QEvent对象,会自动删除 | 无法自动删除,需要在栈上创建QEvent对象(系统释放) |
5.事件处理函数:
函数非常多,但这里只总结经常使用到的。
QMouseEvent,QWheelEvent
void mouseDoubleClickEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void wheelEvent(QWheelEvent *event);
QKeyEvent,QTimerEvent
void keyPressEvent(QKeyEvent *event);
void keyReleaseEvent(QKeyEvent *event);
void timerEvent(QTimerEvent *event);