Qt的事件过滤器installEventFilter

2023-11-07

一、介绍

WPF中使用AddHandler来监听事件,那么QT呢?Qt的事件模型是使用一个QObject对象,来监视发送其他QObject对象的事件,在事件到达之前对其进行处理。这里要使用一个函数

void QObject::installEventFilter(QObject *filterObj)

Qt助手的解释如下:

在对象上安装一个事件过滤器filterObj。如下:

 monitoredObj->installEventFilter(filterObj);

其中monitoredObj、filterObj都是QObject的子类。上面代码意思是:在monitoredObj对象上安装一个事件过滤器filterObj。该函数一般和如下函数配合使用:

[virtual] bool QObject::eventFilter(QObject *watched, QEvent *event)

注意:该函数是虚函数,也就是说派生自QObject的子类可以重写该函数。

上面monitoredObj对象安装一个filterObj过滤器后,则可以在filterObj对象所在类的eventFilter函数

 class KeyPressEater : public QObject
  {
      Q_OBJECT
      ...
 
  protected:
      bool eventFilter(QObject *obj, QEvent *event) override;
  };
 
  bool KeyPressEater::eventFilter(QObject *obj, QEvent *event)
  {
      if (event->type() == QEvent::KeyPress) {
          QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
          qDebug("Ate key press %d", keyEvent->key());
          return true;
      } else {
          // standard event processing
          return QObject::eventFilter(obj, event);
      }
  }

现在我们在按钮或QListView两个窗体部件上安装过滤器,如下:

      KeyPressEater *keyPressEater = new KeyPressEater(this);
      QPushButton *pushButton = new QPushButton(this);
      QListView *listView = new QListView(this);
     
      pushButton->installEventFilter(keyPressEater);
      listView->installEventFilter(keyPressEater);

二、实例

dialog.h

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include<QLabel>
#include<QHBoxLayout>
#include<QVBoxLayout>
#include<QPixmap>
#include<QMouseEvent>
#include<QImage>
namespace Ui {
class Dialog;
}

class Dialog : public QDialog
{
    Q_OBJECT

public:
    explicit Dialog(QWidget *parent = 0);
    ~Dialog();
public:
    QLabel * label1;
    QLabel * label2;
    QLabel * label3;
    QLabel * labelstate;
    QImage image1;
    QImage image2;
    QImage image3;

private:
    Ui::Dialog *ui;
private slots:
    bool eventFilter(QObject *, QEvent *);
};

#endif // DIALOG_H

dialog.cpp

#include "dialog.h"
#include "ui_dialog.h"

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);

    label1 = new QLabel;
    label2 = new QLabel;
    label3 = new QLabel;
    labelstate = new QLabel;
    labelstate->setAlignment(Qt::AlignHCenter);

    image1.load(":/BABY.jpg");
    image2.load(":/baby.jpg");
    image3.load(":/huanhuan.jpg");

    QMatrix matrix;
    matrix.scale(0.3, 0.3);
    image1 = image1.transformed(matrix);
    image2 = image2.transformed(matrix);
    image3 = image3.transformed(matrix);

    label1->setPixmap(QPixmap::fromImage(image1));
    label2->setPixmap(QPixmap::fromImage(image2));
    label3->setPixmap(QPixmap::fromImage(image3));

    QHBoxLayout * hor = new QHBoxLayout;
    hor->addWidget(label1);
    hor->addWidget(label2);
    hor->addWidget(label3);

    QVBoxLayout * ver = new QVBoxLayout;
    ver->addLayout(hor);
    ver->addWidget(labelstate);
    setLayout(ver);

    label1->installEventFilter(this);
    label2->installEventFilter(this);
    label3->installEventFilter(this);



}
bool Dialog::eventFilter(QObject *watched, QEvent *event)
{
    //判断当前发生事件的对象
    if (watched == label1)
    {
        if (event->type() == QEvent::MouseButtonPress) //判断发生的事件类型
        {
            //将事件event转化为鼠标事件
            QMouseEvent * mouseEvent = (QMouseEvent *)event;
            if (mouseEvent->button()&Qt::LeftButton)
            {
                labelstate->setText(tr("Left mouse button pressed on left image"));
            }
            if (mouseEvent->button()&Qt::RightButton)
            {
                labelstate->setText(tr("middle mouse button pressed on left image"));
            }
            if (mouseEvent->button()&Qt::MidButton)
            {
                labelstate->setText(tr("right mouse button pressed on left image"));
            }
            QMatrix matrix;
            matrix.scale(2, 2);
            QImage tmp1 = image1.transformed(matrix);
            label1->setPixmap(QPixmap::fromImage(tmp1));
        }
        if (event->type() == QEvent::MouseButtonRelease)
        {
            labelstate->setText(tr("Mouse button released from left image"));
            label1->setPixmap(QPixmap::fromImage(image1));

        }
    }
    if (watched == label2)
    {
        if (event->type() == QEvent::MouseButtonPress)
        {
            QMouseEvent * mouseEvent = (QMouseEvent *)event;
            if (mouseEvent->button()&Qt::LeftButton)
            {
                labelstate->setText(tr("Left mouse button pressed on middle image"));
            }
            if (mouseEvent->button()&Qt::RightButton)
            {
                labelstate->setText(tr("middle mouse button pressed on middle image"));
            }
            if (mouseEvent->button()&Qt::MidButton)
            {
                labelstate->setText(tr("right mouse button pressed on middle image"));
            }
            QMatrix matrix;
            matrix.scale(2, 2);
            QImage  tmp2 = image2.transformed(matrix);
            label2->setPixmap(QPixmap::fromImage(tmp2));
        }
        if (event->type() == QEvent::MouseButtonRelease)
        {
            labelstate->setText(tr("Mouse button released from middle image"));
            label2->setPixmap(QPixmap::fromImage(image2));
        }

    }
    if (watched == label3)
    {
        if (event->type() == QEvent::MouseButtonPress)
        {
            QMouseEvent * mouseEvent = (QMouseEvent *)event;
            if (mouseEvent->button()&Qt::LeftButton)
            {
                labelstate->setText(tr("Left mouse button pressed on right image"));
            }
            if (mouseEvent->button()&Qt::RightButton)
            {
                labelstate->setText(tr("middle mouse button pressed on right image"));
            }
            if (mouseEvent->button()&Qt::MidButton)
            {
                labelstate->setText(tr("right mouse button pressed on right image"));
            }
            QMatrix matrix;
            matrix.scale(2, 2);
            QImage  tmp3 = image3.transformed(matrix);
            label3->setPixmap(QPixmap::fromImage(tmp3));
        }
        if (event->type() == QEvent::MouseButtonRelease)
        {
            labelstate->setText(tr("Mouse button released from right image"));
            label3->setPixmap(QPixmap::fromImage(image3));
        }
    }
    //调用QDialog::eventFilter将事件交给上层对话框
    return QDialog::eventFilter(watched, event);

}


Dialog::~Dialog()
{
    delete ui;
}

参考:

installEventFilter、eventFilter函数理解_荆楚闲人的博客-CSDN博客_installeventfilter

 QT学习之一:安装事件过滤器(installEventFilter)_隨意的風的博客-CSDN博客

 

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Qt的事件过滤器installEventFilter 的相关文章

  • 右键单击 QPushButton 上的 contextMenu

    对于我的应用程序 我在 Qt Designer 中创建了一个 GUI 并将其转换为 python 2 6 代码 关于一些QPushButton 与设计器创建 我想添加右键单击上下文菜单 菜单选项取决于应用程序状态 如何实现这样的上下文菜单
  • 在 4K 屏幕上使用 Matplotlib 和 TKAgg 或 Qt5Agg 后端

    我在 Ubuntu 16 04 上使用 Matplotlib 2 0 和 Python 3 6 来创建数据图 电脑显示器的分辨率为 4k 分辨率为 3840x2160 绘图数字看起来非常小 字体也很小 我已经尝试过TKAgg and Qt5
  • QGraphicsScene没有删除QWidget的功能

    QGraphicsScene 有一个addWidget QWidget 有函数 但是没有对应的removeWidget QWidget 它只有removeItem QGraphicsItem 如何删除 QWidget 这是一个基本示例 看看
  • 另一个宏中的 Q_PROPERTY 宏

    如何放置Q PROPERTY另一个宏里面 辅助宏 define SimpleAllinOne member type public void Set member type arg member m member arg member ty
  • 具有多个父项的 Qt 树模型

    我想构建一棵树 其中一个元素可以引用另一个元素 我想要构建的树是 像这样的东西 A B C D E F P this is a pointer to C D first child of C E second child of C I fo
  • Qml 和模糊图像

    我想使用 QML 实现模糊效果 我找到了有关 效果 模糊 的参考资料 例子 http qt gitorious org lscunha qt components lscunha qt components blobs d78feec567
  • QML:无法读取未定义的属性“xxx”

    ApplicationWindow id root property string rootName rootName visible true width 800 height 400 title qsTr WatchFace Maker
  • 如何在 Qt Creator 中编辑 QtWebKit 的右键上下文菜单?

    好吧 这是我的困境 我正在使用 Qt Creator 制作一个使用 Webkit 的简单应用程序 我认为 Qt Creator 会有一种简单的方法来使用信号和槽编辑器编辑右键单击上下文菜单 但事实证明这不是真的 我知道 webkit 有与上
  • 如何使用 Qt DOM 通过此语法获取 xml 属性

    我正在使用 Qt DOM XML 解析器 并且遇到了如下属性定义的问题
  • 如何让小部件在上下文菜单出现时接收鼠标释放事件

    在Ubuntu20 04上 当上下文菜单出现时 我无法让小部件接收鼠标释放事件 而Windows可以接收 我的pyqt版本是5 15 2 我考虑过手动发送鼠标释放事件 但我不知道当上下文菜单出现时哪些系统会收到鼠标释放事件 这样做可能会导致
  • 如何去除QWizard中的水平线?

    我正在研究一个样式表QWizard我想删除按钮上方的水平线 我尝试递归浏览所有小部件并将其边框设置为无 但似乎没有任何小部件具有此边框 这是我的代码 可以找到完整的可构建示例here https gist github com ardeid
  • QML 中可重用的字体属性[重复]

    这个问题在这里已经有答案了 在 QML 中 我希望能够定义一组字体属性以进行简单的语义重用 例如 代替 Text text This is a header font family Encode Sans weight Font Black
  • QTableView 并双击一个单元格

    我正在开发测试用例编辑器 该编辑器包含 USART 传输和接收数据包格式 编辑器是一个表格视图 发送和接收数据包的长度为八个字节 例如 0x01 0x02 0x03 0x08 它在我的第五和第六栏中 现在 我希望此列中的单元格为只读 但是当
  • Qt:不完整类型和前向声明的使用无效

    我有一些误解 A h ifndef A H define A H include B h class A public B Q OBJECT public A endif A cpp include A h A A B ui gt blan
  • 针对初学者的 QT 商业许可证与非商业许可证 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 QT 许可似乎非常反学习 因为据我所知 用它开发的任何东西都只能是商业的当且仅当 its entire开发是在使用商业许可证的情况下完成的
  • Qt 5.1.1 与 Visual Studio 2012 - 这些 QT 版本无法访问

    打开 Visual Studio 时出现此错误 我安装自http qt project org downloads http qt project org downloads 适用于 Windows 64 位的 Qt 5 1 1 VS 20
  • 连接到 QNetworkReply::error 信号

    我正在使用 Qt5 的新连接语法 QNetworkReply 有一个名为error http qt project org doc qt 5 0 qtnetwork qnetworkreply html error 2还有一个函数叫做err
  • 如何在Android中使用QML - QWebView

    我想在 Android 中部署一个 YouTube 应用程序 但它只能在我的电脑上运行 在安卓上不起作用 它不加载任何视频 问题仅出在 QWebView 上 我使用了与此类似的代码 http doc qt io archives qt 5
  • 了解 Qt3D 创建的网格

    我创建了一个 Qt3D 网格 如下所示 Qt3DCore QEntity newEntity new Qt3DCore QEntity Qt3DExtras QConeMesh mesh new Qt3DExtras QConeMesh m
  • 通过引用传递 [C++]、[Qt]

    我写了这样的东西 class Storage public Storage QString key const int value const void add item QString int private QMap

随机推荐

  • 【虚幻】清理缓存文件(C盘占用过大)

    使用UE4时 引擎的默认编译文件保存在C盘 久了会使C盘爆满 这样子 我们需要先清理调C盘现有的缓存文件 然后修改一下缓存路径 一 清理C盘缓存 缓存文件位置C Users 用户名 AppData Local UnrealEngine Co
  • pygame无法在屏幕上显示中文(已解决)

    方法1 用系统自己带的字体 C Windows Fonts里面查看 然后 front pygame front SysFront simHei 50 字体大小是50 一般不需要输入文件路径 text 青铜 文字内容 render12 fro
  • pymysql fetchone () , fetchall () , fetchmany ()用法与区别

    1 定义 1 1 fetchone 返回单个的元组 也就是一条记录 row 如果没有结果 则返回 None 1 2 fetchall 返回多个元组 即返回多个记录 rows 如果没有结果 则返回 首先 fetchone 函数它的返回值是单个
  • React基础-生命周期

    1 引出生命周期 unmountComponentAtNode 卸载组件 componentDidMount 组件挂载完毕 componentWillReceiveProps 组件将要接受参数 子组件将要接受新参数时触发的生命周期函数 sh
  • 【JavaWeb】练习五

    1 gt 过滤器实现登录过滤 WebFilter urlPatterns do initParams WebInitParam name driver value com mysql jdbc Driver public class Log
  • Springboot 拦截器,拦截所有请求,判断是否登录,验证权限

    Java的三大器 拦截器的作用 Java里的拦截器是动态拦截Action调用的对象 它提供了一种机制可以使开发者在一个Action执行的前后执行一段代码 也可以在一个Action执行前阻止其执行 同时也提供了一种可以提取Action中可重用
  • libevent 事件循环

    include
  • Dubbo zookeeper 初探

    原文地址 http blog csdn net wxwzy738 article details 16330383 转 http blog csdn net u011270461 article details 12144623 建议参考资
  • 信息隐藏技术--图像置乱

    图像置乱 图像置乱是信息隐藏技术的一种 图像置乱后图像无法辨认 可以达到对图像信息的隐藏和保护作用 分类 空域置乱 频域置乱 空频域混合置乱 图像置乱对信息起到了隐藏和保护的作用 既可以对信息进行加密传送 也可以作为图像处理的预处理 图像置
  • Spring系列文章:Bean的获取⽅式

    一 简介 Spring为Bean提供了多种实例化 式 通常包括4种 式 也就是说在Spring中为Bean对象的创建准 备了多种 案 的是 更加灵活 第 种 通过构造 法实例化 第 种 通过简单 模式实例化 第三种 通过factory be
  • ffmpeg中sws_scale()用法实例

    ffmpeg中sws scale 用法实例 视频编码 2009 06 30 10 02 27 阅读1185 评论0 字号 大 中 小 订阅 Copyright C 2003 Michael Niedermayer
  • vue 表单相互校验

    这里举例校验姓和名的长度和不少于3
  • 4个java死锁工具:jstack、jconsole、jvisualvm、jmc

    在 Java 中 死锁 Deadlock 情况是指 两个或两个以上的线程持有不同系统资源的锁 线程彼此都等待获取对方的锁来完成自己的任务 但是没有让出自己持有的锁 线程就会无休止等待下去 线程竞争的资源可以是 锁 网络连接 通知事件 磁盘
  • GB28181视频监控国标平台EasyGBS角色绑定设备通道的功能优化

    GB28181视频监控国标平台EasyGBS是基于国标GB28181协议 支持多路设备同时接入的视频监控 视频云服务平台 支持对多平台 多终端分发RTSP RTMP FLV HLS WebRTC等格式的视频流 国标GB28181平台Easy
  • go网站收藏

    golang修养之路 go每日新闻 go语言社区 go语言设计与实现
  • 报错解决:Process finished with exit code -1073741819 (0xC0000005)

    简单记录一下程序异常终止 抛出 Process finished with exit code 1073741819 0xC0000005 的解决方法 一 程序中文件位置错误 缺少文件 位置错误1 如果使用相对路径的话 推荐换成绝对路径进行
  • 剑指 Offer 11. 旋转数组的最小数字(java+python)

    把一个数组最开始的若干个元素搬到数组的末尾 我们称之为数组的旋转 给你一个可能存在 重复 元素值的数组 numbers 它原来是一个升序排列的数组 并按上述情形进行了一次旋转 请返回旋转数组的最小元素 例如 数组 3 4 5 1 2 为 1
  • Java日志的占位符

    如果日志中是集合 且集合的对象为基本数据类型 那么占位符和基本数据类型保持一致 如果集合对象为自定义对象 那么需要获取对应的实例后再获取对应的属性 看属性的基本数据类型 如果不需要获取属性 就把对象toString后用 s接收 payloa
  • Parse方法解析字符串

    今天才注意到Parse方法解析字符串时可以通过NumberStyles枚举和IFormatProvider接口分析字符串的格式
  • Qt的事件过滤器installEventFilter

    一 介绍 WPF中使用AddHandler来监听事件 那么QT呢 Qt的事件模型是使用一个QObject对象 来监视发送其他QObject对象的事件 在事件到达之前对其进行处理 这里要使用一个函数 void QObject installE