Qt-窗口消息处理机制及拦截消息的五种方法

2023-11-18

【Qt 拦截消息的五种方法】

  1. 覆写框架类QCoreApplication的notify函数,这个函数将得到整个框架中所有窗口的消息
  2. 给框架类安装一个消息过滤器 QCoreApplication->nativeEventFilter(filterObj),这种我们代码没有实现
  3. 给某窗口安装一个消息过滤器 QPushButton->installEventFilter(filterObj)
  4. 继承某窗口并覆写event函数(该函数负责某个窗口中派发所有子消息)
  5. 继承某窗口并覆写窗口的某个子消息

以上介绍的几种方法结构图如下:

20150623134228

【代码示例】

下面代码演示了上面介绍的 1、3、4、5 四种方法,由于第二种非常难演示并且与第一种功能类似,所以我们没有做示例。

代码一共分7个文件:

  1. capplication.h:继承 QApplication 的类 CApplication 类
  2. capplication.cpp:继承 QApplication 的类 CApplication 类的功能实现
  3. cpushbutton.h:继承 QPushButton 的类 CPushButton 类
  4. cpushbutton.cpp:继承 QPushButton 的类 CPushButton 类的功能实现
  5. cwidget.h:继承 QWidget 的类 CWidget 类
  6. cwidget.cpp:继承 QWidget 的类 CWidget 类的实现
  7. main.cpp:实例化框架和窗口对象并显示窗口
#ifndef CAPPLICATION_H
#define CAPPLICATION_H

#include <QApplication>
#include <QDebug>

class CApplication : public QApplication
{
public:
    CApplication(int argc, char* argv[]);

    bool notify(QObject *, QEvent *);
};

#endif // CAPPLICATION_H
#include "capplication.h"

CApplication::CApplication(int argc, char* argv[])
    :QApplication(argc, argv)
{

}

bool CApplication::notify(QObject *obj, QEvent *ev)
{
    // 根据窗口名字判断是否是 CWidget 窗口类的消息
    if (obj->objectName() == "widgets")
    {
        // 判断消息类型是不是鼠标点击消息
        if (ev->type() == QEvent::MouseButtonPress)
        {
            qDebug() << "在窗口中点击了鼠标!";
        }
    }
    // 将消息交还给父窗口处理,避免消息丢失
    QApplication::notify(obj, ev);
}
#ifndef CPUSHBUTTON_H
#define CPUSHBUTTON_H

#include <QPushButton>
#include <QDebug>
#include <QMouseEvent>

class CPushButton : public QPushButton
{
public:
    CPushButton();

    void mousePressEvent(QMouseEvent *e);
    void mouseReleaseEvent(QMouseEvent *e);

};

#endif // CPUSHBUTTON_H
#include "cpushbutton.h"

CPushButton::CPushButton()
{

}

void CPushButton::mousePressEvent(QMouseEvent *e)
{
    qDebug() << "截获鼠标按下消息...";
    // 因为最底层的消息没有返回值
    // 可以调用accept函数告知父类已经处理过该消息
    e->accept();
}

void CPushButton::mouseReleaseEvent(QMouseEvent *e)
{
    qDebug() << "截获鼠标弹起消息...";
    // 表示对此消息不感兴趣,交由父类的消息处理函数去处理。
    // 实际我们已经在这个消息处理函数中打印了一句话
    // 这样父类、子类都会对这个消息做处理
    e->ignore();
}
#ifndef CWIDGET_H
#define CWIDGET_H

#include <QWidget>
#include <QObject>
#include <QEvent>
#include "cpushbutton.h"

class CWidget : public QWidget
{
    Q_OBJECT
public:
    explicit CWidget(QWidget *parent = 0);

    CPushButton* _button;

    bool eventFilter(QObject *, QEvent *);

signals:

public slots:
};

#endif // CWIDGET_H
#include "cwidget.h"

CWidget::CWidget(QWidget *parent) : QWidget(parent)
{
    // 设置自身窗口的名字,好让父类可以识别这个窗口进行消息处理
    this->setObjectName("widgets");
    _button = new CPushButton;
    _button->setText("button");
    _button->setParent(this);
    _button->installEventFilter(this);
}

bool CWidget::eventFilter(QObject *obj, QEvent *ev)
{
    // 判断对象是否是 button 对象
    if (obj == _button)
    {
        // 判断消息是否是单击消息
        if (ev->type() == QEvent::MouseButtonPress)
        {
            // 对鼠标单击处理...
        }
    }
    // 把消息交还给父类处理,这样消息就不会丢失
    QWidget::eventFilter(obj, ev);
}
#include "capplication.h"
#include "cwidget.h"

int main(int argc, char* argv[])
{
    CApplication app(argc, argv);

    CWidget w;
    w.show();

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

Qt-窗口消息处理机制及拦截消息的五种方法 的相关文章

  • 双线性序列给出奇数结果

    我试图让我的表现技能 不存在 达到标准 但在将公式写入代码时遇到了问题 这是我试图将其引用为 转换 为代码的公式 考虑一个序列 u 其中 u 定义如下 号码u 0 1是第一个u 对于每个x in u then y 2 x 1 and z 3
  • 对静态成员变量的未定义引用

    我有一个有静态成员的类 它也是我的程序中其他几个类的基类 这是它的头文件 ifndef YARL OBJECT HPP define YARL OBJECT HPP namespace yarlObject class YarlObject
  • 如何使用 ILoggerFactory 记录 Polly 的重试

    或者 如何从静态方法记录 From https github com App vNext Polly https github com App vNext Polly你有这样的例子 其中记录器神奇地可用 Policy Timeout 30
  • 如何在线程创建和退出时调用函数?

    include
  • Linux 使用 boost asio 拒绝套接字绑定权限

    我在绑定套接字时遇到问题 并且以用户身份运行程序时权限被拒绝 这行代码会产生错误 acceptor new boost asio ip tcp acceptor io boost asio ip tcp endpoint boost asi
  • 使用预编译头减少 clang 编译时间

    我正在开发一个数据库项目 该项目将查询 以某种高级语言表示 编译为 C 代码 这段代码由数据库编译并执行 那部分工作得很好 现在 我正在尝试减少 C 查询代码的编译时间 我想知道是否可以使用预编译头来提高性能 该查询被转换为一个名为 Que
  • Confuser .NET 混淆器。安全吗? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我目前正在开发一个应用程序 其中阻止用户反编译代码非常重要 现在 我意识到 如果由经验丰富的程序员执行 大多数 exe 都是可反编译的
  • C++:将模板参数的模板类型成员添加为好友的正确语法?

    我有一个带有模板类型参数 tTRAIT 的类 我想加一个模板为好友type member aliastTRAIT 但我无法弄清楚语法 这可能吗 template
  • 求一个数的因数。无法得到准确的结果

    有人可以帮助纠正我的算法吗 我已经对几个数字进行了测试 但它没有输出完整的因式分解 对于具有大量因子的数字 它完全失败 int num 20 for int i 2 i lt num i if num i 0 cout lt lt i lt
  • 在 C++ 中使用表达式模板进行符号微分

    如何在 C 中使用表达式模板实现符号微分 一般来说 您需要一种表示符号的方法 即编码的表达式模板 例如3 x x 42 以及一个可以计算导数的元函数 希望您对 C 中的元编程足够熟悉 知道这意味着什么和需要什么 但可以给您一个想法 This
  • ASP.NET MVC 中 ModelState.AddModelError 中的关键参数有什么意义?

    我在我的控制器中添加了验证检查来修改ModelState如果验证失败 例如 private bool ValidateMoney string raw string name decimal min decimal max try var
  • 带有自定义鉴别器的 EntityFramework Code First 继承

    我正在尝试在 EntityFramework Code First 中映射以下继承 public class Member public string ProjectName get set public string AssemblyNa
  • 数组与映射的性能

    我必须循环一个大数组中的元素子集 其中每个元素都指向另一个元素 问题来自于检测大图中的连接组件 我的算法如下 1 考虑第一个元素 2 将下一个元素视为前一个元素所指向的元素 3 循环直到没有发现新元素 4 考虑1 3中尚未考虑的下一个元素
  • 该组件没有由 uri 标识的资源

    我想创建一个通用数据网格以在我的所有视图 用户控件上使用 这是我的结构 Class Library called Core Class called ViewBase public class ViewBase UserControl pu
  • TreeView:仅在子节点中存在复选框

    我需要一个树视图控件 根节点没有复选框 只有图像 所有子节点都有一个复选框 图像 C net 2 0 winforms 不是 wpf WinForms树视图默认不支持混合复选框 非复选框节点 您可以在树视图上全局启用复选框 并使用以下命令在
  • 非静态类中的静态方法和静态类中的静态方法有什么区别?

    我有两个班级A级和B级 static class ClassA static string SomeMethod return I am a Static Method class ClassB static string SomeMeth
  • 参数数量在编译时确定的 Lambda 函数

    我想声明一个带有 N 个参数的 lambda 函数 其中 N 是模板参数 就像是 template
  • 为什么我不能对普通变量进行多态?

    我是一名Java程序员 最近开始学习C 我对某事感到困惑 据我了解 在 C 中 要实现多态行为 您必须使用指针或引用 例如 考虑一个类Shape与实施的方法getArea 它有几个子类 每个子类都以不同的方式重写 getArea 然后考虑以
  • 未找到 _sqlite3_open 等符号错误

    您好 我收到此错误 Undefined symbols sqlite3 open referenced from main in ccRlWVer o sqliite3 close referenced from main in ccRlW
  • 如何在给定点停止线程?

    我试图停止一些线程 阅读一些有关优雅地执行此操作的正确方法的内容 但我一定做错了什么 因为它根本不起作用 起初我尝试不使用lock with IsRunning不稳定 然后尝试使用锁 这是我所拥有的 private volatile boo

随机推荐

  • 2023年华为od机试 Java【刻录光盘备份】

    前言 python代码 链接 JavaScript代码 链接 题目 有一系列文件需要通过光盘备份 每张光盘的容量固定为500MB 文件的大小均为整数MB并且不超过500MB 文件不可拆分或分卷备份 需要确定最少需要多少张光盘来完成备份 输入
  • ngnix+lua+js埋点 实现自定义日志采集

    ngnix lua js埋点 实现自定义日志采集 1 收集数据的页面 js埋点 在想要手机数据的页面预先放一段js代码 当用户发生行为时 触发js方法 收集数据 发到后端 http 192 168 4 101 index html 这里的i
  • 在Windons子系统ubuntu中安装ssh(保姆级教程)

    1 什么是ssh SSH Secure Shell 是一种用于远程登录和安全文件传输的网络协议 SSH服务是在计算机上运行的服务程序 它允许用户通过网络安全地远程访问计算机并执行各种操作 以下是关于SSH服务的一些重要信息 远程登录 SSH
  • 流操作

    StreamReader 与 FileStream 的区别用法 有关StreamReader的内容参考http blog sina com cn s blog 796ffec50100te51 html StreamReader 旨在以一种
  • “互联网+”最可行的路径就是“社群+”

    互联网 最可行的路径就是 社群 36氪的朋友们 2016 04 05 17 04 文章摘要 商业正从物以类聚走向人以群分 编者按 本文作者 卢彦 原文来自微信公众号 互联网思维 ID webthinking 36 氪经授权转载 前不久阿里
  • 【C++】通讯录管理系统

    1 系统功能介绍与展示 2 创建项目 3 菜单功能 代码 封装函数显示该界面 如 void showMenu 在main函数中调用封装好的函数 include
  • jmeter批量上传图片, csv文件参数化——详细讲解

    我们在测试的过程中 需要把图片放到请求中 而且还需要不一样的图片 批量修改图片后缀 我们也可以吧文件生成我们想要的后缀 1 首先创建一个文本txt 在文本中输入 ren jpg png 然后把txt的文件 修改 成bat后缀的 进行双击 在
  • 关于Altium Designer PCB元器件的3D封装

    关于Altium Designer PCB元器件的3D封装 虽然Altium Designer为我们提供了丰富的元件封装库资源 但是 在实际的电路设计中电子元器件技术的不断更新换代 有些特定的元器件封装仍需要我们自行制作 另外 有时根据工程
  • python3 中 dict和list 效率比较

    import time def count time func def int time args kwargs start time time time 程序开始时间 res func args kwargs over time time
  • 给 Ubuntu 操作系统配置静态 IP

    针对 Ubuntu 22 04 3 操作系统的静态 IP 配置 一 查看初始的网络信息 查看网卡名称 ifconfig 查看网关信息 route n 二 编辑网络配置文件 编辑文件 配置文件的名称可能不一样 自己去 etc netplan
  • 手把手教你Modelsim仿真【2020.4版本】

    首先新建一个文件夹 test5 打开Modelsim 依次选择 File gt Change Directory 把目录选择到创建的 test5 文件夹 创建库 依次选择 File gt New gt Library 一般我们选择第三个 库
  • 软文营销如何吸引用户情感意识引起共鸣

    当今互联网营销铺天盖地 自网络开始普及后 网络营销发展速度非常快 然而 我们需要在众多营销中取胜就需要技术创新 不管平台如何变化 有一个要素仍然至关重要 写好广告文案 因为文案内容才是读者了解你的关键所在 今天178软文网小编将分享我们最好
  • 大模型开发:从数据挖掘到智能应用

    在当今的数字化时代 数据的生成和处理已经成为一项重要的战略任务 随着大数据技术的发展 企业 组织以及个人对海量数据的需求越来越大 这也就催生了数据挖掘算法模型开发的快速发展 数据挖掘算法模型开发是一种从大量数据中提取有价值信息的过程 这些信
  • 国服ps4如何修改服务器地址,国服ps4如何修改服务器地址

    国服ps4如何修改服务器地址 内容精选 换一换 本节介绍如何查看云服务器的mac地址 云服务器的mac地址不支持修改 登录Linux云服务器 执行以下命令 查看云服务器的mac地址 ifconfig查看MAC地址ifconfig登录Linu
  • 【3分钟速读】运营到底是干啥的?

    欢迎关注天善智能 我们是专注于商业智能BI 人工智能AI 大数据分析与挖掘领域的垂直社区 学习 问答 求职一站式搞定 作者 陈老师 在咨询行业打拼了10 年 在如何诊断经营问题 建立分析体系 解决专项问题上有超过30个大型项目积累与实战 天
  • 时间序列预测(一)基于Prophet的销售额预测

    时间序列预测 一 基于Prophet的销售额预测 小O 小H 有没有什么方法能快速的预测下未来的销售额啊 小H Facebook曾经开源了一款时间序列预测算法fbprophet 简单又快速 传统的时间序列算法很多 例如AR MA ARIMA
  • 创建对象的几种方式

    一 工厂模式 工厂模式解决了创建相似对象的问题 但却没有解决对象识别的问题 怎样知道一个对象的类型 function createPerson name age job var o new Object o name name o age
  • 走进大数据,感受大数据

    摘要 大数据时代已经到来 现阶段 我国大数据产业发展如何 大数据应用领域在哪 大数据价值在哪里 带着这些疑问 走进大数据 感受大数据带来的神奇魔力 关注作者 需要大数据学习视频资料 其他文章可以找到大师组织 2017年9月8日 腾讯董事会主
  • shapley和树的shap

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 shapley and shap Shapley交互阶的计算 关于树结构Shap的计算 Shapley交互阶的计算 首先一阶的计算公式 二阶 交互值 计算 三阶计算 一般式
  • Qt-窗口消息处理机制及拦截消息的五种方法

    Qt 拦截消息的五种方法 覆写框架类QCoreApplication的notify函数 这个函数将得到整个框架中所有窗口的消息 给框架类安装一个消息过滤器 QCoreApplication gt nativeEventFilter filt