提示:欢迎小伙伴的点评✨✨,相互学习c/c++应用开发。🍳🍳🍳
博主🧑🧑 本着开源的精神交流Qt开发的经验、将持续更新续章,为社区贡献博主自身的开源精神👩🚀
文章目录
- 前言
- 一、事件过滤及实例概述
- 二、效果实例
- 三、原码实例
- eventfilter.h
- eventfilter.cpp
- main.cpp
- EventFilter解析
- 四、总结
前言
本章节会给大家带来Qt5 事件处理及实例——事件过滤及实例详解。
一、事件过滤及实例概述
Qt 的事件模型中提供的事件过滤器功能使得 一个 QObject 对象可以监视另 一个 QObject 对象中的事件,通过在一个 QObject 对象中安装事件过滤器,可以在事件到达该对象前捕获事件,从而起到监视该对象事件的作用。
例如, Qt 已经提供了 QPushButton 用千表示一个普通的按钮类。如果需要实现一个动态的图片按钮,即当鼠标键按下时按钮图片发生变化,则需要同时响应鼠标按下等事件。
二、效果实例
三个图片分别对应三个 QLabel 对象 。 当用鼠标键按下某个图片时,图片大小会发生变化;而释放鼠标键时,图片又恢复初始大小,并且程序将提示当前事件的状态信息,如鼠标键类型、被鼠标键按下的图片序号。
新建Resources 并建立image文件 添加现有Src将tu.png图片放入其中
图一
图二
三、原码实例
eventfilter.h
#ifndef EVENTFILTER_H
#define EVENTFILTER_H
#include <QDialog>
#include <QLabel>
#include <QImage>
#include <QEvent>
class EventFilter : public QDialog
{
Q_OBJECT
public:
EventFilter(QWidget *parent = 0);
~EventFilter();
public slots:
bool eventFilter(QObject *, QEvent *);
private:
QLabel *label1;
QLabel *label2;
QLabel *label3;
QLabel *stateLabel;
QImage Image1;
QImage Image2;
QImage Image3;
};
#endif // EVENTFILTER_H
eventfilter.cpp
#include "eventfilter.h"
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QMouseEvent>
#include <QMatrix>
EventFilter::EventFilter(QWidget *parent)
: QDialog(parent)
{
setWindowTitle(tr(" 事件过滤")) ;
label1 = new QLabel;
Image1.load(":/Src/13.png");
label1->setAlignment (Qt::AlignHCenter|Qt::AlignVCenter);
label1->setPixmap(QPixmap::fromImage(Image1));
label2 = new QLabel;
Image2.load(":/Src/14.png");
label2->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
label2->setPixmap(QPixmap::fromImage(Image2));
label3 = new QLabel;
Image3.load(":/Src/15.png");
label3->setAlignment (Qt::AlignHCenter|Qt::AlignVCenter);
label3->setPixmap(QPixmap::fromImage(Image3));
stateLabel = new QLabel(tr("鼠标键按下标志"));
stateLabel->setAlignment(Qt::AlignHCenter);
QHBoxLayout *layout=new QHBoxLayout;
layout->addWidget(label1);
layout->addWidget(label2);
layout->addWidget(label3);
QVBoxLayout *mainLayout = new QVBoxLayout(this);
mainLayout->addLayout(layout);
mainLayout->addWidget(stateLabel);
label1->installEventFilter(this);
label2->installEventFilter(this);
label3->installEventFilter(this);
/* installEventFilterO函数为每一个图片安装事件过滤器,
* 指定整个窗体为监视事件的对象,函数原型如下:
* void QObject::installEventFilter
* (
* QObject * filterObj
* )
* 参数 filterObj 是监视事件的对象,此对象可以通过 eventFilter()函数接收事件。如果某个事
* 件需要被过滤,即停止正常的事件响应,则在 eventFilter()函数中返回 true, 否则返回 false 。
* QObject 的 removeEventFilter() 函数可以解除已安装的事件过滤器。
*/
}
EventFilter::~EventFilter()
{
}
/*QObject 的事件监视函数 eventFilter()的具体实现*/
bool EventFilter::eventFilter(QObject *watched, QEvent *event)
{
if(watched==label1) //首先判断当前发生事件的对象
{
///判断发生的事件类型
if(event->type()==QEvent::MouseButtonPress)
{
//将事件 event 转化为鼠标事件
QMouseEvent *mouseEvent= (QMouseEvent *) event;
/**以下根据鼠标键的类型分别显示*/
if (mouseEvent->buttons()&Qt::LeftButton)
{
stateLabel->setText(tr("左键按下左边图片"));
}
else if (mouseEvent->buttons ()&Qt::MidButton)
{
stateLabel->setText(tr(" 中键按下左边图片"));
}else if(mouseEvent->buttons()&Qt::RightButton)
{
stateLabel->setText(tr(" 右键按下左边图片")) ;
}
/*显示缩小的图片*/
QMatrix matrix;
matrix.scale(1.8,1.8);
QImage tmpimg=Image1.transformed(matrix);
label1->setPixmap(QPixmap::fromImage(tmpimg));
}
/*鼠标释放事件的处理,恢复图片的大小*/
if(event->type()==QEvent::MouseButtonRelease)
{
stateLabel->setText(tr(" 鼠标释放左边图片")) ;
label1->setPixmap(QPixmap::fromImage(Image1));
}
}else if(watched==label2)
{
///判断发生的事件类型
if(event->type()==QEvent::MouseButtonPress)
{
//将事件 event 转化为鼠标事件
QMouseEvent *mouseEvent= (QMouseEvent *) event;
/**以下根据鼠标键的类型分别显示*/
if (mouseEvent->buttons()&Qt::LeftButton)
{
stateLabel->setText(tr("左键按下中间图片"));
}
else if (mouseEvent->buttons ()&Qt::MidButton)
{
stateLabel->setText(tr(" 中键按下中间图片"));
}else if(mouseEvent->buttons()&Qt::RightButton)
{
stateLabel->setText(tr(" 右键按下中间图片")) ;
}
/*显示缩小的图片*/
QMatrix matrix;
matrix.scale(1.8,1.8);
QImage tmpimg=Image2.transformed(matrix);
label2->setPixmap(QPixmap::fromImage(tmpimg));
}
/*鼠标释放事件的处理,恢复图片的大小*/
if(event->type()==QEvent::MouseButtonRelease)
{
stateLabel->setText(tr(" 鼠标释放中间图片")) ;
label2->setPixmap(QPixmap::fromImage(Image2));
}
}else if(watched==label3)
{
///判断发生的事件类型
if(event->type()==QEvent::MouseButtonPress)
{
//将事件 event 转化为鼠标事件
QMouseEvent *mouseEvent= (QMouseEvent *) event;
/**以下根据鼠标键的类型分别显示*/
if (mouseEvent->buttons()&Qt::LeftButton)
{
stateLabel->setText(tr("左键按下右边图片"));
}
else if (mouseEvent->buttons ()&Qt::MidButton)
{
stateLabel->setText(tr(" 中键按下右边图片"));
}else if(mouseEvent->buttons()&Qt::RightButton)
{
stateLabel->setText(tr(" 右键按下右边图片")) ;
}
/*显示缩小的图片*/
QMatrix matrix;
matrix.scale(1.8,1.8);
QImage tmpimg=Image3.transformed(matrix);
label3->setPixmap(QPixmap::fromImage(tmpimg));
}
/*鼠标释放事件的处理,恢复图片的大小*/
if(event->type()==QEvent::MouseButtonRelease)
{
stateLabel->setText(tr(" 鼠标释放右边图片")) ;
label3->setPixmap(QPixmap::fromImage(Image3));
}
}
//将事件交给上层对话框
return QDialog::eventFilter(watched,event);
}
main.cpp
#include "eventfilter.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
EventFilter w;
w.show();
return a.exec();
}
EventFilter解析
- void QObject::installEventFilter (QObject* filterObj);
把filterObj对象安装(或注册)为事件过滤器,filterObj也称为过滤器对象。事件过滤器通常在构造函数中进行注册。 - bool QObject::eventFilter(QObject* obj, QEvent* e);
来接收拦截到的事件。也就是说拦截到的事件在filterObj对象中的eventFilter函数中处理。eventFilter的第一个参数obj指向的是事件本应传递到的目标对象。 - 使用QObject::removeEventFilter(QObject *obj);函数可以删除事件过滤器。
四、总结
Qt5 事件处理及实例——事件过滤及实例会在应用程序开发中经常用到的。