Qt 事件过滤器 - EventFilter

事件过滤器,见名之意,就是将事件过滤一遍,将不需要的事件都清除掉,剩下需要的事件进行操作。

可能讲得不是很透彻,那就看下图,就很明白了:
Qt 事件过滤器 - EventFilter_第1张图片

原本事件应该直接发送给“组件对象”,但是现在却先将事件发送给“过滤器对象”,经过过滤的事件再发给“组件对象”。

如上,可以将事件过滤器这么理解,但是本人并不是这样理解的。
个人觉得事件过滤器的一个重要用法就是给那些没有鼠标事件和键盘事件的部件添加这些事件操作。

例如,label部件没有鼠标事件,当我们有这方面的项目需求时,就可以使用事件过滤器;SpinBox没有键盘事件,当我们有这方面的项目需求时,就可以使用事件过滤器。

事件过滤器的操作:

  1. 首先给需要添加事件过滤器的部件注册监听对象
    对象名->installEventFilter(true);

  2. 重写eventFilter(QObject *obj, QEvent *event)函数进行处理。


写一个小例子:
在项目ui文件上托两个label部件和一个spinBox部件。
并准备一张图片。

最后实现的效果是:
鼠标单击图片,然后在label中显示是鼠标那个键点击了图片;
当按下键盘空格键,spinBox部件显示值0,放开部件显示99.
Qt 事件过滤器 - EventFilter_第2张图片

根据需要添加头文件:
#include // 鼠标事件头文件
#include // 键盘事件头文件


写代码

首先将部件进行注册
指定整个窗体为监视事件的对象

ui.spinBox->installEventFilter(this);
ui.label->installEventFilter(this);

为一个label设置图片吧

ui.label->setPixmap(QPixmap(QString("fly1.png")));
ui.label->setFixedSize(ui.label->pixmap()->size());

然后重写eventFilter进行操作

首先使用参数obj进行与绑定的控件对象进行判断,是否与其相等;然后在使用参数event->type()的返回值与枚举鼠标或者键盘进行判断;最后将event转换为鼠标事件对象或者键盘对象事件,就可以进行操作了。

public slots:
	bool eventFilter(QObject *, QEvent *) override;


bool EventFilter::eventFilter(QObject *obj, QEvent *event) {

	if (obj == ui.label) {		// 判断过滤对象

		// 鼠标按下事件的处理
		if (event->type() == QEvent::MouseButtonPress) {	
			QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);	// 转换为鼠标事件对象

			if (mouseEvent->button() == Qt::LeftButton) {		// 鼠标左键按下
				ui.label_2->setText(QString("左键按下图片"));
			}
			if (mouseEvent->button() == Qt::MidButton) {			// 鼠标中键按下
				ui.label_2->setText(QString("中间按下图片"));
			}
			if (mouseEvent->button() == Qt::RightButton) {		// 鼠标右键按下
				ui.label_2->setText(QString("右键按下图便"));
			}
		}

		if (event->type() == QEvent::MouseButtonRelease) {		// 鼠标释放
			ui.label_2->setText(QString("鼠标释放图片"));
		}

	}


	if (obj == ui.spinBox) {
		if (event->type() == QEvent::KeyPress) {	// 键盘按下
			QKeyEvent *key = static_cast<QKeyEvent *>(event);
			if (key->key() == Qt::Key_Space) {
				ui.spinBox->setValue(0);
			}
		}

		if (event->type() == QEvent::KeyRelease) {	// 键盘释放
			ui.spinBox->setValue(100);
		}
	}


	// 事件交给上层对话框进行处理
	return QDialog::eventFilter(obj, event);
}

总结:

注意:不是所有控件都有鼠标事件或者键盘事件,例如label就没有键盘事件,如果硬是写代码进行判断,是无法操作;spinBox没有鼠标事件等。
好像是只能有其中一种似的,不是很懂这些。
这些是经验所得,测试了很久才总结出来的。除非给部件单独写鼠标事件或者键盘事件。

你可能感兴趣的:(Qt,过滤器,qt)