QT的事件机制

QT的事件机制

文章目录

    • QT的事件机制
  • 1、QT的事件机制。
  • 2、QT事件的整体流程。
    • 1、事件处理函数。
      • 1、鼠标按下与鼠标释放事件。
      • 2、事件的接收与忽略(accept()和ignore()函数)。
    • 2.事件的分发enevt()
      • 1、事件分发的dome。
      • 2、enevt事件的缺点。
    • 3、事件的过滤器。
  • 3、总结


1、QT的事件机制。

事件(event)是由系统或者 Qt 本身在不同的时刻发出的。当用户按下鼠标、敲下键盘,或者是窗口需要重新绘制的时候,都会发出一个相应的事件。一些事件是****用户操作做出响应时发出,如键盘事件等;另一些事件则是由系统自动发出,如计时器事件。

在前面我们也曾经简单提到,Qt 程序需要在main()函数创建一个QApplication对象,然后调用它的exec()函数。这个函数就是开始 Qt 的事件循环。在执行exec()函数之后,程序将进入事件循环来监听应用程序的事件。当事件发生时,Qt 将创建一个事件对象。Qt 中所有事件类都继承于QEvent。在事件对象创建完毕后,Qt 将这个事件对象传递给QObject的event()函数。event()函数并不直接处理事件,而是按照事件对象的类型分派给特定的事件处理函数(event handler)。

2、QT事件的整体流程。

如图所示:
在这里插入图片描述
app.exe()--------->事件过滤器----->事件分发器-----------------》事件处理函数

下面依次从下往上介绍。

1、事件处理函数。

1、鼠标按下与鼠标释放事件。

提升一个按钮。重写鼠标按下与鼠标释放事件。
mybutton.h

#include <QWidget>
#include <QPushButton>
#include <QMouseEvent>
#include <QEvent>
class MyButton : public QPushButton
{Q_OBJECT
public:explicit MyButton(QWidget *parent = nullptr);//鼠标点击事件void mousePressEvent(QMouseEvent *ev);//鼠标释放事件void mouseReleaseEvent(QMouseEvent *ev);
signals:
};

mybutton.cpp

#include "mybutton.h"
#include <QDebug>MyButton::MyButton(QWidget *parent): QPushButton{parent}
{}void MyButton::mousePressEvent(QMouseEvent *ev)
{qDebug() << "鼠标按下" ;
}
void MyButton::mouseReleaseEvent(QMouseEvent *ev)
{qDebug() << "鼠标抬起" ;
}

结果如下:
在这里插入图片描述
注意:按钮是提升自定义mybutton类。而mybutton又是继承于QPushButton

2、事件的接收与忽略(accept()和ignore()函数)。

mybutton.h

#include <QWidget>
#include <QPushButton>
#include <QMouseEvent>
#include <QEvent>class MyButton : public QPushButton
{Q_OBJECT
public:explicit MyButton(QWidget *parent = nullptr);//鼠标点击事件void mousePressEvent(QMouseEvent *ev);signals:};

mybutton.cpp

#include "mybutton.h"
#include <QDebug>MyButton::MyButton(QWidget *parent): QPushButton{parent}
{}void MyButton::mousePressEvent(QMouseEvent *ev)
{if(ev->button() == Qt::LeftButton){qDebug() << "MyButton鼠标按下的是左键";ev->accept(); // accept 事件不会再往下传递}else // 鼠标的右键按下与鼠标的中间按键往下传递{qDebug() << "MyButton鼠标其他键按下";QPushButton::mousePressEvent(ev);}
}

myWidget.h

#include <QWidget>\
class MyWidget : public QWidget
{Q_OBJECTpublic:MyWidget(QWidget *parent = nullptr);~MyWidget();//鼠标点击事件void mousePressEvent(QMouseEvent *ev);
private:Ui::MyWidget *ui;
};

myWidget.cpp

#include "mywidget.h"
#include "ui_mywidget.h"MyWidget::MyWidget(QWidget *parent): QWidget(parent), ui(new Ui::MyWidget)
{ui->setupUi(this);
}MyWidget::~MyWidget()
{delete ui;
}void MyWidget::mousePressEvent(QMouseEvent *ev)
{if(ev->button() == Qt::LeftButton){qDebug() << "MyWidget鼠标左键按下";}else {qDebug() << "MyWidget鼠标其他键按下";}
}

在myWidget类与mybutton类都有重写鼠标事件。
现在accept()函数
当鼠标的左键按下时的打印:
在这里插入图片描述
对鼠标的左键按下不在往下发所以myWidget收不到
当鼠标的右键按下时的打印:
在这里插入图片描述
对鼠标的右键按下往下发所以myWidget能收到

当代码把accept()函数改成ignore()函数。鼠标左键按下事件继续往下传递。传递给了父组件mywidget

void MyButton::mousePressEvent(QMouseEvent *ev)
{if(ev->button() == Qt::LeftButton){qDebug() << "MyWidget鼠标左键按下";ev->ignore(); //忽略,事件继续往下传递,给谁传递?//事件传递给了父组件,不是给父类(基类)}else // 鼠标的右键按下与鼠标的中间按键往下传递{qDebug() << "MyButton鼠标其他键按下";QPushButton::mousePressEvent(ev);}
}

以上就是事件的接收与忽略。就是accept()函数与ignore()函数。

2.事件的分发enevt()

1、事件分发的dome。

函数原型: bool event(QEvent *ev)
event()函数主要用于事件的分发。所以,如果你希望在事件分发之前做一些操作,就可以重写这个event()函数了。
myWidget.h

#include <QWidget>
class MyWidget : public QWidget
{Q_OBJECTpublic:MyWidget(QWidget *parent = nullptr);~MyWidget();bool event(QEvent *ev);     // 重写event事件void keyPressEvent(QKeyEvent *event); //键盘按下事件void keyReleaseEvent(QKeyEvent *event);
private:Ui::MyWidget *ui;
};

myWidget.cpp

#include "mywidget.h"
#include "ui_mywidget.h"MyWidget::MyWidget(QWidget *parent): QWidget(parent), ui(new Ui::MyWidget)
{ui->setupUi(this);
}MyWidget::~MyWidget()
{delete ui;
}bool MyWidget::event(QEvent *e)
{if(e->type() == QEvent::KeyPress) /* 按键按下的分发 */{/* 类型转换 */QKeyEvent *env = static_cast<QKeyEvent *>(e);if(env->key() == Qt::Key_0){qDebug() << "event Qt::Key_0";return QWidget::event(e); /* 只处理按键0 */}return true; /* 其他按键不分发下去 */} else {return QWidget::event(e); /* 其他的事件都分发下去 */}
}void MyWidget::keyPressEvent(QKeyEvent *event) //键盘按下事件
{switch(event->key()) {case Qt::Key_0:qDebug() <<"Qt::Key_0";break;case Qt::Key_1:qDebug() <<"Qt::Key_1";break;}
}void MyWidget::keyReleaseEvent(QKeyEvent *event)
{qDebug() <<"MyWidget::keyReleaseEvent";
}

总结:当按下按键0按下才处理。其他按键不起作用。
按键0按下的结果:
在这里插入图片描述
其他按键按下不起作用。只打印按键释放。因为如上return QWidget::event(e); /* 其他的事件都分发下去 */
按键是否是可以打印的。如果改成return true; 就不会打印按键释放。

2、enevt事件的缺点。

在这里插入图片描述
从而引出事件过滤器。
在这里插入图片描述
在这里插入图片描述

3、事件的过滤器。

函数原型如下:virtual bool QObject::eventFilter ( QObject * watched, QEvent * event )
watched:过滤哪个控件 event:过滤哪个事件。

这个函数正如其名字显示的那样,是一个“事件过滤器”。所谓事件过滤器,可以理解成一种过滤代码。事件过滤器会检查接收到的事件。如果这个事件是我们感兴趣的类型,就进行我们自己的处理;如果不是,就继续转发。这个函数返回一个 bool 类型,如果你想将参数 event 过滤出来,比如,**不想让它继续转发,就返回 true,否则返回 false。**事件过滤器的调用时间是目标对象(也就是参数里面的watched对象)接收到事件对象之前。也就是说,如果你在事件过滤器中停止了某个事件,那么,watched对象以及以后所有的事件过滤器根本不会知道这么一个事件。
mybutton.h

#include <QPushButton>
class MyButton : public QPushButton
{Q_OBJECT
public:explicit MyButton(QWidget *parent = nullptr);void mouseMoveEvent(QMouseEvent *ev);
signals:};

mybutton.cpp

#include "mybutton.h"
#include <QDebug>MyButton::MyButton(QWidget *parent): QPushButton{parent}
{}
void MyButton::mouseMoveEvent(QMouseEvent *ev)
{qDebug() << "mouseMoveEvent";QPushButton::mousePressEvent(ev);
}

mywidget.h

#include <QWidget>
class MyWidget : public QWidget
{Q_OBJECT
public:MyWidget(QWidget *parent = nullptr);~MyWidget();//事件过滤器bool eventFilter(QObject *obj, QEvent *e);
private:Ui::MyWidget *ui;
};

mywidget.cpp

#include "mywidget.h"
#include "ui_mywidget.h"MyWidget::MyWidget(QWidget *parent): QWidget(parent), ui(new Ui::MyWidget)
{ui->setupUi(this);//安装过滤器ui->pushButton->installEventFilter(this);ui->pushButton->setMouseTracking(true);/* 按钮追踪 */
}MyWidget::~MyWidget()
{delete ui;
}bool MyWidget::eventFilter(QObject *obj, QEvent *e)
{if(obj == ui->pushButton){QMouseEvent *env = static_cast<QMouseEvent *>(e);//判断事件if(e->type() == QEvent::MouseMove){ui->pushButton->setText(QString("eventFilter:(%1, %2)").arg(env->x()).arg(env->y()));return true; /* 不分发 */}else{return QWidget::eventFilter(obj, e);}return true;}else{return QWidget::eventFilter(obj, e);}
}

如上 return true; /* 不分发 */ 所以 qDebug() << “mouseMoveEvent”;没有打印
如果设置return false; 事件不会过滤。就会打印mouseMoveEvent
总结:
在这里插入图片描述

3、总结

现在我们可以总结一下 Qt 的事件处理,实际上是有五个层次:
在这里插入图片描述
上面1, 2,3,点用的多。4, 5不怎么用。
事件过滤器与enevt事件,以及事件的处理函数都是虚函数继承与上层父类。我们在重写时虚函数必须继承上层父类一致。否则就不叫重写。

以上就是今天要讲的内容,QT的事件。主要理解QT从上到下的流程。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/622239.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

通过本质看现象:关于Integer受内部初始化赋值范围限制而出现的有趣现象

文/朱季谦 这是我很多年前的第一篇技术博客&#xff0c;当时作为一名技术小菜鸟&#xff0c;总体而言显得很拙见&#xff0c;但也算是成长路上的一个小脚印&#xff0c;希望能在以后的日子里&#xff0c;可以对JAVA技术有一个更加深入的思考与认识。 前几天我在逛论坛的时候&a…

SSM基础入门

SSM Mybatis、Spring和SpringMVC这三个框架整合在一起完成业务功能开发 文章目录 SSM5.1 流程5.2 详细步骤5.2.1 基本配置5.2.2 功能模块开发5.2.3 测试5.2.3.1 单元测试5.2.3.2 PostMan测试 5.3 统一结果封装5.3.1 概念5.3.2 实现 5.4 统一异常处理5.4.1 异常处理器的使用5.4…

Linux Centos7静默安装(非图形安装)Oracle RAC 11gR2(Oracle RAC 11.2.0.4)

Oracle RAC (全称Oracle Real Application Clusters &#xff09;静默安装&#xff08;非图形安装&#xff09;教程。 由于这篇文章花费了我太多时间&#xff0c;设置了仅粉丝可见&#xff0c;见谅。 环境说明&#xff1a; 虚拟机软件&#xff1a;VMware Workstation 16 Pro…

Git与VScode联合使用详解

目录 Git与VScode联合使用 方式一 1. 用vscode打开文件夹&#xff0c;如图点击初始化仓库&#xff0c;把此仓库初始为git仓库。 2. 提交文件到本地仓库 3. vscode与github账号绑定 4. 在github中建立远程仓库 5. 本地仓库与远程仓库绑定 方式二 1. 在github上建立远程仓…

VSCode添加Python解释器并安装Python库

目录 一、安装VSCode 二、安装Python解释器 1、安装包链接 2、安装过程 3、测试 4、安装flake8和yapf两个包 &#xff08;1&#xff09;安装flake8包 &#xff08;2&#xff09;安装yapf包 三、VSCode中选择python解释器 一、安装VSCode VSCode安装教程&#xff08;默…

Windows之任意文件删除到提权

前言 ZDI 发表过从任意文件夹删除到提权的利用过程&#xff0c;还提供了任意文件删除到提权的利用过程&#xff0c;所以一字之差但是漏洞利用方式也是有细微偏差的。 这里把任意文件删除和任意文件夹删除漏洞提权结合起来分析&#xff0c;是因为其最后的利用过程是一样的&…

认识监控系统zabbix

利用一个优秀的监控软件&#xff0c;我们可以: ●通过一个友好的界面进行浏览整个网站所有的服务器状态 ●可以在 Web 前端方便的查看监控数据 ●可以回溯寻找事故发生时系统的问题和报警情况 了解zabbix zabbix是什么&#xff1f; ●zabbix 是一个基于 Web 界面的提供分布…

JVM:从零到入门

JVM&#xff0c;就是Java虚拟机。 JVM是一个巨大的话题&#xff0c;我们本文主要简单介绍一些围绕JVM相关的基础知识。 目录 JVM内存区域划分 本地方法栈 虚拟机栈 堆 程序计数器 方法区/ 元数据区 类加载 1.加载 2.验证 3.准备 4.解析 5.初始化 双亲委派模型 …

yydict属性字典-一种更加方便的方式访问字典

yydict属性字典-一种更加方便的方式访问字典 问题引入 这篇文章是想介绍 最近在使用字典的一种困惑. 我希望通过少写几个字符来访问 python中字典这种数据结构. 比如这个例子: person {name: frank,age: 18,hobby: swimming }在python中字典的定义 如上面的例子, 如果我希…

spring boot mybatis plus mapper如何自动注册到spring bean容器

##Import(AutoConfiguredMapperScannerRegistrar.class) ##注册MapperScannerConfigurer ##MapperScannerConfigurer.postProcessBeanDefinitionRegistry方法扫描注册mapper ##找到mapper候选者 ##过滤mapper 类 候选者 ##BeanDefinitionHolder注册到spring 容器

vue项目之.env文件.env.dev、test、pro

.env文件是vue运行项目时的环境配置文件。 .env: 全局默认配置文件&#xff0c;所有环境(开发、测试、生产等&#xff09;均会加载并合并该文件 .env.development(开发环境默认命名) 开发环境的配置&#xff0c;文件名默认为.env.development,如果需要改名也是可以的&#xf…

【Python】使用pyinstaller打包为Windows平台的xxx.exe方法步骤

pyinstaller 是一个用于将 Python 代码打包成独立可执行文件的工具&#xff0c;它可以将 Python 代码打包成 Windows、Linux、Mac 等平台的可执行文件&#xff0c;方便用户在不同环境中运行。 pyinstaller用法&#xff1a; 1.安装pyinstaller库&#xff0c;这里以PyCharm环境为…

ACM论文LaTeX模板解析(一)| 模板下载与安装

本文收录于专栏&#xff1a;ACM 论文 LaTeX模板解析&#xff0c;本专栏将会围绕ACM 论文 LaTeX模板解析持续更新。欢迎点赞收藏关注&#xff01; 文章目录 1. 引言2. 下载方式 1. 引言 计算机械协会&#xff08;ACM&#xff0c;Association for Computing Machinery&#xff0…

UG装配-WAVE几何链接器

自上向下&#xff08;自顶向下&#xff09;设计 先将产品主要结构&#xff08;或主要部件&#xff09;建立好&#xff0c;然后再根据要求设计其它组件&#xff0c;使每个组件之间有数据关联&#xff0c;适用于产品开发初期&#xff0c;便于修改&#xff0c;修改组件数据后&…

基于JavaWeb的酒店管理系统

基于JavaWeb的酒店管理系统 文章目录 基于JavaWeb的酒店管理系统系统介绍技术选型成果展示源码获取账号地址及其他说明 系统介绍 基于JavaWeb的酒店管理系统是为酒店打造的管理平台&#xff0c;其主要功能有管理员登陆、客房预订、客房入住、房间管理、数据查询(预订单查询、入…

PySide6/PyQt6中的时间管理类:QTime的使用方法

文章目录 📖 介绍 📖🏡 环境 🏡📒 使用方法 📒📝 创建QTime对象📝 常用方法⚓️ 相关链接 ⚓️📖 介绍 📖 QTime是PySide6中用于处理时间段的类,可以用来表示一天中的时间,例如小时、分钟和秒。它提供了许多操作和格式化时间的功能,使得处理时间变得更加…

mysql-实战案例 (超详细版)

&#x1f389;欢迎您来到我的MySQL基础复习专栏 ☆* o(≧▽≦)o *☆哈喽~我是小小恶斯法克&#x1f379; ✨博客主页&#xff1a;小小恶斯法克的博客 &#x1f388;该系列文章专栏&#xff1a;重拾MySQL &#x1f379;文章作者技术和水平很有限&#xff0c;如果文中出现错误&am…

VL53L4CD TOF开发(1)----驱动TOF进行测距

VL53L4CX TOF开发.1--驱动TOF进行测距 概述视频教学样品申请完整代码下载主要特点硬件准备技术规格系统框图应用示意图生成STM32CUBEMX选择MCU串口配置IIC配置 XSHUTX-CUBE-TOF1演示结果 概述 VL53L4CD适用于接近测量和短距离测量&#xff0c;可实现从仅仅1 mm到1300 mm的超精…

SAP SD-DN-MM 交货单相关物料凭证的视图的日期问题

眼下有个需求 获取交货单对应的物料凭证的过账日期BLDAT。 同步BW数据过去 新增一个数据库视图 但是实际使用时&#xff0c;有效部分仅本月&#xff0c;再选择条件里面要加上 MATdoc-bldat > sy-datum - sydatum6(2). 于是使用ST05 跟踪了一下&#xff0c;发现在DD28S…

echarts——折线图实现不同区间不同颜色+下钻/回钻功能——技能提升

echarts——折线图实现不同区间不同颜色下钻/回钻功能——技能提升 需求场景解决步骤1&#xff1a;安装echarts插件解决步骤2&#xff1a;html代码解决步骤3&#xff1a;封装option配置和initChart渲染方法解决步骤4&#xff1a;回钻功能 需求场景 最近在写后台管理系统时&…