【Qt开发流程】之事件过滤器及sendEvent和postEvent

2023-12-05

描述

事件过滤器(Event Filter)是Qt中一个强大的事件处理机制,它可以在对象接收到事件之前截获事件,并进行自定义处理。事件过滤器可以在不修改对象自身代码的前提下,对其进行事件处理和拦截。

事件过滤器的使用过程如下:

  1. 创建一个 QObject 对象,为其安装事件过滤器。

  2. 重载事件过滤器的 eventFilte r函数,实现自定义的事件拦截和处理。

  3. 在需要拦截和处理事件的对象上,调用 installEventFilter 函数,将事件过滤器安装到该对象上。

  4. 在事件过滤器中实现自定义事件处理逻辑。

  5. 在事件过滤器的eventFilter函数中,调用 QObject::eventFilter() 函数,将事件传递给下一个事件接收器,事件接收器可以是该对象本身或者其父对象。

使用事件过滤器可以对 QWidget QApplication QCoreApplication 等对象进行事件处理,常用于实现自定义事件处理逻辑、事件日志等。

示例

以下是用于拦截并处理 QLineEdit 对象的按键事件,实现只能输入数字:

#include <QDebug>
#include <QObject>
#include <QLineEdit>
#include <QKeyEvent>
#include <QRegExp>

class DigitFilter : public QObject
{
    Q_OBJECT
public:
    explicit DigitFilter(QObject *parent = nullptr) : QObject(parent){
        m_regExp.setPattern("[a-zA-Z0-9]+$");
    }

    bool eventFilter(QObject *obj, QEvent *event) override
    {
        qDebug().noquote() << "[" << __FILE__ << __LINE__ << "]" <<  event->type();
        if(event->type() == QEvent::KeyPress) {
            QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
            if(isDigit(keyEvent->text().at(0)) && m_regExp.exactMatch(keyEvent->text()))
                return false;
            else
                return true;
        }else {
            return QObject::eventFilter(obj, event);
        }
    }

private:
    bool isDigit(const QChar &c)
    {
        return c >= QLatin1Char('0') && c <= QLatin1Char('9');
    }

private:
    QRegExp m_regExp;
};

// main.cpp
#include <QApplication>
#include <QLineEdit>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QLineEdit lineEdit;
    DigitFilter digitFilter;
    lineEdit.installEventFilter(&digitFilter);

    lineEdit.show();

    return a.exec();
}

以上代码作用:

  • 在上述代码中,新建了一个名为DigitFilter的QObject子类,该类继承QObject类并重载了eventFilter函数,该函数用于拦截QLineEdit对象的按键事件,并判断该事件传递的按键是否为数字,如果是则返回false,否则返回true。
  • 使用installEventFilter函数将该事件过滤器安装到QLineEdit对象上,从而实现只能输入数字的功能。

sendEvent()

bool QCoreApplication::sendEvent(QObject *receiver, QEvent *event);

使用notify()函数将事件事件直接发送给接收者。返回从事件处理程序返回的值。
事件发送后不会被删除。通常的方法是在堆栈上创建事件,例如:

	QMouseEvent event(QEvent::MouseButtonPress, pos, 0, 0, 0);
    QApplication::sendEvent(mainWindow, &event);

postEvent()

void QCoreApplication::postEvent(QObject *receiver, QEvent *event, int priority = Qt::NormalEventPriority)

将事件事件(以对象接收者作为事件接收者)添加到事件队列并立即返回。
事件必须在堆上分配,因为post事件队列将获得事件的所有权,并在事件被发布后将其删除。在事件发布之后再访问它是不安全的。
当控制返回到主事件循环时,存储在队列中的所有事件都将使用notify()函数发送。
事件按优先级降序排序,即高优先级事件排在低优先级事件之前。优先级可以是任何整数值,即在INT_MAX和INT_MIN之间,包括;更多细节可以参考 Qt::EventPriority 。具有同等优先级的事件将按发布的顺序处理。
注意:这个函数是线程安全的。

示例

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QEvent>

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

    //ui->lineEdit->installEventFilter(new DigitFilter);

    ui->spinBox->installEventFilter(this);
    ui->spinBox->setFocus();
    QKeyEvent e(QEvent::KeyPress, Qt::Key_Up, Qt::NoModifier);
    QApplication::sendEvent(ui->spinBox, &e);
}

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

bool MainWindow::eventFilter(QObject *watched, QEvent *event)
{
    if(watched == ui->spinBox)
    {
        if(event->type() == QEvent::KeyPress)
        {
            QKeyEvent* e = static_cast<QKeyEvent*>(event);
            if(e->key() == Qt::Key_Space)
            {
                ui->spinBox->setValue(0);
                return true;
            }else {
                return false;
            }
        }else {
            return false;
        }
    }else {
        return QMainWindow::eventFilter(watched, event);
    }
}

运行后, spinBox 控件的值变为了1.
在这里插入图片描述

结论

万事开头难,然后中间难,最后结尾难

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

【Qt开发流程】之事件过滤器及sendEvent和postEvent 的相关文章

  • 如何将 Java 赋值表达式转换为 Kotlin

    java中的一些东西就像 int a 1 b 2 c 1 if a b c System out print true 现在它应该转换为 kotlin 就像 var a Int 1 var b Int 2 var c Int 1 if a
  • 如何在一行中将字符串数组转换为双精度数组

    我有一个字符串数组 String guaranteedOutput Arrays copyOf values values length String class 所有字符串值都是数字 数据应转换为Double QuestionJava 中
  • 在Windows上安装Java 11 OpenJDK(系统路径问题)

    Java 11 最近发布了 众所周知 这个版本没有安装文件 当然 要在没有安装程序的情况下安装 Java 我将系统设置 PATH 和 JAVA HOME 设置为解压缩 Java 11 的文件夹的地址 根据对类似问题的已接受回复建议 唯一的事
  • 如何测试 JUnit 测试的 Comparator?

    我需要测试 Compare 方法 但我对如何测试感到困惑 我可以看看该怎么做吗 public class MemberComparator implements Comparator
  • 如何查找 Android 设备中的所有文件并将它们放入列表中?

    我正在寻求帮助来列出 Android 外部存储设备中的所有文件 我想查找所有文件夹 包括主文件夹的子文件夹 有办法吗 我已经做了一个基本的工作 但我仍然没有得到想要的结果 这不起作用 这是我的代码 File files array file
  • Java8无符号算术

    据广泛报道 Java 8 具有对无符号整数的库支持 然而 似乎没有文章解释如何使用它以及有多少可能 有些函数 例如 Integer CompareUnsigned 很容易找到 并且似乎可以实现人们所期望的功能 但是 我什至无法编写一个简单的
  • 在浏览器中点击应用程序时播放框架挂起

    我正在 Play 中运行一个应用程序activator run 也许 5 次中有 3 次 它会挂起 当我去http localhost 9000 它就永远坐在那里旋转 我看到很多promise timed out错误也 我应该去哪里寻找这个
  • Convert.FromBase64String 方法的 Java 等效项

    Java 中是否有相当于Convert FromBase64String http msdn microsoft com en us library system convert frombase64string aspx which 将指
  • hibernate总是自己删除表中的所有数据

    您好 我正在开发一个 spring mvc 应用程序 它使用 hibernate 连接到存储文件的 mysql 数据库 我有两个方法 一个方法添加我选择的特定文件路径中的所有文件 另一种方法调用查询以返回从 mysql 存储的文件列表 问题
  • OnClick 事件中的 finish() 如何工作?

    我有一个Activity一键退出Activity 通过layout xml我必须设置OnClick事件至cmd exit调用 this finish 效果很好 public void cmd exit View editLayout thi
  • Prim 的迷宫生成算法:获取相邻单元格

    我基于 Prim 算法编写了一个迷宫生成器程序 该算法是 Prim 算法的随机版本 从充满墙壁的网格开始 选择一个单元格 将其标记为迷宫的一部分 将单元格的墙壁添加到墙壁列表中 While there are walls in the li
  • 在具有相同属性名称的不同数据类型上使用 ModelMapper

    我有两节课说Animal AnimalDto我想用ModelMapper将 Entity 转换为 DTO 反之亦然 但是对于具有相似名称的一些属性 这些类应该具有不同的数据类型 我该如何实现这一目标 动物 java public class
  • 如何在 JFreeChart TimeSeries 图表上显示降雨指数和温度?

    目前 我的 TimeSeries 图表每 2 秒显示一个位置的温度 现在 如果我想每2秒显示一次降雨指数和温度 我该如何实现呢 这是我的代码 import testWeatherService TestWeatherTimeLapseSer
  • org.jdesktop.application 包不存在

    几天以来我一直在构建一个 Java 桌面应用程序 一切都很顺利 但是今天 当我打开Netbeans并编译文件时 出现以下编译错误 Compiling 9 source files to C Documents and Settings Ad
  • Windows 上的 Nifi 命令

    在我当前的项目中 我一直在Windows操作系统上使用apache nifi 我已经提取了nifi 0 7 0 bin zip文件输入C 现在 当我跑步时 bin run nifi bat as 管理员我在命令行上看到以下消息 但无法运行
  • Springs 元素“beans”不能具有字符 [children],因为该类型的内容类型是仅元素

    我在 stackoverflow 中搜索了一些页面来解决这个问题 确实遵循了一些正确的答案 但不起作用 我是春天的新人 对不起 这是我的调度程序 servlet
  • 如何测试 spring-security-oauth2 资源服务器安全性?

    随着 Spring Security 4 的发布改进了对测试的支持 http docs spring io spring security site docs 4 0 x reference htmlsingle test我想更新我当前的
  • 将 JTextArea 内容写入文件

    我在 Java Swing 中有一个 JTextArea 和一个 提交 按钮 需要将textarea的内容写入一个带有换行符的文件中 我得到的输出是这样的 它被写为文件中的一个字符串 try BufferedWriter fileOut n
  • KeyPressed 和 KeyTyped 混淆[重复]

    这个问题在这里已经有答案了 我搜索过之间的区别KeyPressedand KeyTyped事件 但我仍然不清楚 我发现的一件事是 Keypressed 比 KeyTyped 首先被触发 请澄清一下这些事件何时被准确触发 哪个适合用于哪个目的
  • JAVA - 如何从扫描仪读取文件中检测到“\n”字符

    第一次海报 我在读取文本文件的扫描仪中读取返回字符时遇到问题 正在读取的文本文件如下所示 test txt start 2 0 30 30 1 1 90 30 0 test txt end 第一行 2 表示两个点 第二行 位置索引 0 xp

随机推荐

  • 【车载开发系列】Flash支持的安全功能

    车载开发系列 Flash支持的安全功能 这里写目录标题 车载开发系列 Flash支持的安全功能 一 FlashMemory概念 二 Flash Memory特性 1 包括代码闪存和数据闪存 2 闪存编程方法 3 支持BGO 后台地面操作 4
  • 数据库系统概论复习资料

    数据库系统概论考试需知 一 分值分布 1 判断题 10分 1分一个 2 填空题 20分 2分一个 3 选择题 20分 2分一个 4 分析题 30分 第一题10分 第二题20分 5 综合题 20分 二 考试范围 1 计科1 4班 1 2 3
  • HDMI之数据岛

    概述 发送端在发送视频信号之前 将多媒体信息通过数据岛传输给接收端 接收端通过数据岛信息获取当前分辨率 VIC 编码信息 RGB YCR等 色彩空间 位深等等 然后对应将视频信息解码 与此同时 多余的带宽用于传输音频信息等 本文通过具体的包
  • 凌晨!比特币突破4万美元,本轮上涨分析与未来展望!

    比特币在上周五 1日 成功突破38000美元大关后 就持续震荡走高 在今晨06 30左右 更是一举突破4万大关 最高来到41750美元 再度刷下2023年新高 以太坊 ETH 在差不多同样时间 最高来到2265美元 刷新年内新高 近24小时
  • [足式机器人]Part2 Dr. CAN学习笔记-Ch0-1矩阵的导数运算

    本文仅供学习使用 本文参考 B站 DR CAN Dr CAN学习笔记 Ch0 1矩阵的导数运算 1 标量向量方程对向量求导 分母布局 分子布局 1 1 标量方程对向量的导数 1 2 向量方程对向量的导数 2 案例分析 线性回归 3 矩阵求导
  • [足式机器人]Part4 南科大高等机器人控制课 Ch01 Linear Differential Equations and Matrix Exponential

    本文仅供学习使用 本文参考 B站 CLEAR LAB 课程主讲教师 Prof Wei Zhang 南科大高等机器人控制课 Ch01 Linear Differential Equations and Matrix Exponential 1
  • 法律情境扮演、逆向推理文字游戏、AIGC创作……见证AI极致生产力!

    飞桨星河社区 以飞桨和文心大模型为核心 集开放数据 开源算法 云端GPU算力及大模型开发工具于一体 在大模型范式下 为开发者提供模型与应用的高效开发环境 在成立的5年以来 已汇集660 万AI开发者 覆盖深度学习初学者 在职开发者 企业开发
  • DOSBOX 快捷键及 MS-DOS 命令

    1 全屏 退出全屏 alt enter 2 释放鼠标 ctrl F10 3 exit 退出DOSBOX 4 dir 显示目录内容 可选参数 w 只显示文件名 P 显示部分内容 exe 筛选出可执行文件 5 cd 进入目录 cd 退回上一级目
  • 现在的00后,实在是太卷了......

    现在的小年轻真的卷得过分了 前段时间我们公司来了个00年的 工作没两年 跳槽到我们公司起薪18K 都快接近我了 后来才知道人家是个卷王 从早干到晚就差搬张床到工位睡觉了 最近和他聊了一次天 原来这位小老弟家里条件不太好 一大家子指望他一个人
  • 【Qt开发流程】之事件系统3:键盘事件

    序章 以下链接是拖放事件介绍和使用示例 Qt开发流程 之拖放操作1 介绍链接 https blog csdn net MrHHHHHH article details 134626484 Qt开发流程 之拖放操作2 使用链接 https b
  • 西南科技大学模拟电子技术实验六(BJT电压串联负反馈放大电路)预习报告

    一 计算 设计过程 BJT 电压串联负反馈放大电路 图1 1 1 1为BJT电压串联负反馈放大实验电路 若需稳定输出电压 减小从信号源所取电流 可引入电压串联负反馈闭合开关 图1 1 1 1 理论算法公式 1 闭环电压放大倍数 2 反馈系数
  • 揭开 Java on Azure 开发工具未来6个月路线图的神秘面纱

    作者 Jialuo Gan Program Manager Developer Division at Microsoft 排版 Alan Wang 大家好 欢迎来到 Java on Azure 工具十月份更新 在本次更新中 我们将分享未来
  • 西南科技大学模拟电子技术实验七(集成运算放大器的非线性应用)预习报告

    一 计算 设计过程 说明 本实验是验证性实验 计算预测验证结果 是设计性实验一定要从系统指标计算出元件参数过程 越详细越好 用公式输入法完成相关公式内容 不得贴手写图片 注意 从抽象公式直接得出结果 不得分 页数可根据内容调整 预习计算内容
  • 【Qt开发流程】之定时器事件与随机数示例

    描述 QObject 是所有Qt对象的基类 提供了Qt中基础的定时器支持 通过 QObject startTimer 函数 可以使用毫秒为单位的时间间隔来启动一个定时器 该函数返回一个唯一的整数定时器ID 该计时器现在将以规律的间隔触发 直
  • 深入微服务架构 | 微服务与k8s架构解读

    微服务项目架构解读 什么是微服务 微服务是指开发一个单个小型的但有业务功能的服务 每个服务都有自己的处理和轻量通讯机制 可以部署在单个或多个服务器上 微服务也指一种种松耦合的 有一定的有界上下文的面向服务架构 也就是说 如果每个服务都要同时
  • Unity加载配置文件【解析Json】

    Json 文件 Json文件的存储 存储在StreamingAssets目录下的 这里用了游戏配置表常用的Json存储格式 对象数组 data id 1001 name ScreenFront 1 id 1002 name ScreenLe
  • 深度学习实验八:对自有图片数据集进行预测标注并可视化预测结果

    深度学习实验八 对自有图片数据集进行预测标注并可视化预测结果 一 实验目的 二 实验环境 三 实验内容 1 上传自有数据集 poultry 2 启动训练 3 启动评估 4 计算精度指标 5 预测单张图片并可视化预测结果
  • 人大众读物需求《乡村振兴战略下传统村落文化旅游设计》人民本辉少许

    人大众读物需求 乡村振兴战略下传统村落文化旅游设计 人民本辉少许 人大众读物需求 乡村振兴战略下传统村落文化旅游设计 人民本辉少许
  • 软件测试HR总结的软件测试常见面试题

    一 测试 流程是什么样的 1 产品确定需求后 邀请项目经理 开发 测试等人员参加需求评审会 2 评审结束后开发根据需求文档和接口文档开发 测试制定测试计划和编写手工 测试用例 测试脑图 3 测试召开用例评审 等开发完成后并且进入联调时 可以
  • 【Qt开发流程】之事件过滤器及sendEvent和postEvent

    描述 事件过滤器 Event Filter 是Qt中一个强大的事件处理机制 它可以在对象接收到事件之前截获事件 并进行自定义处理 事件过滤器可以在不修改对象自身代码的前提下 对其进行事件处理和拦截 事件过滤器的使用过程如下 创建一个 QOb