事件过滤器
前面在事件的处理方式中我们提到了事件过滤器;他能在事件到达处理函数之前获取该事件,并且可以实现在一个部件中监控其他多个部件的事件。
使用事件过滤器的步骤:
- 在.h文件中声明;
bool eventFilter(QObject* obj, QEvent * event)
- 在构造函数中为部件安装事件过滤器:
例如:在textEdit 部件安装:ui->textEdit->installEventFilter(this);
- .cpp文件定义事件过滤器;
举个栗子:
在 Widget窗口中加入textEdit部件和spinBox部件,在textEdit中滚动鼠标滑轮可以放大或者缩小字体,在键盘按上下方向键使得spinBox数字自增或者自减。
widget.h文件
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
protected:
bool eventFilter(QObject *obg, QEvent *event);//声明事件过滤器
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
widget.cpp文件
#include "widget.h"
#include "ui_widget.h"
#include <QWheelEvent>
#include <QKeyEvent>
#include <QCoreApplication>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
//安装事件过滤器
ui->spinBox->installEventFilter(this);
ui->textEdit->installEventFilter(this);
// QKeyEvent *event = new QKeyEvent(QEvent::KeyPress,Qt::Key_Up, Qt::NoModifier);
// QCoreApplication::postEvent(ui->spinBox,event);
//次数是为了使用postEvent函数,给spinBox发送一个键盘事件。
//spinBox的默认值1
//使用sendEvent函数发送一个事件
QKeyEvent event(QEvent::KeyPress, Qt::Key_Up, Qt::NoModifier);
QCoreApplication::sendEvent(ui->spinBox,&event);
}
Widget::~Widget()
{
delete ui;
}
bool Widget::eventFilter(QObject *obj, QEvent *event)
{
if(obj == ui->textEdit)
{
if(event->type() == QEvent::Wheel)
{
//将event强制转换为发生的时间类型
QWheelEvent *wheel = static_cast<QWheelEvent *>(event);
if(wheel->delta()>0)
ui->textEdit->zoomIn();//放大
else
ui->textEdit->zoomOut();
return true;
}
else
return false; //如果是其他事件,进一步处理
}
else if(obj == ui->spinBox)
{
if(event->type() == QEvent::KeyPress)
{
QKeyEvent *keyevent = static_cast<QKeyEvent*>(event);
if(keyevent->key() == Qt::Key_Space)
{
ui->spinBox->setValue(0);
return true;
}
else
{
return false;
}
}
else
return false;
}
else return QWidget::eventFilter(obj,event);
}
运行结果大家可自己试试。(默认值是1)
事件的发送
Qt中提供了发送一个事件的功能。有QCoreApplication类的:
bool QCoreApplication::sendEvent(QObject *receiver, QEvent * event)
;
特点:会立即处理给定的事件,event参数在发送完成后不能自动删除,所以对象参数必须在栈上创建。void QCoreApplication::postEvent(QObject *receiver, QEvent * event);
特点:会将事件放到等待调度队列中,当下一次主事件循环运行结束时才会处理他。 event参数发送完成后能自动删除,所以对象参数必须在堆上建立(例如使用new)