QT基础教程(QEvent事件和事件过滤器)

news2024/9/19 10:43:25

文章目录

  • 前言
  • 一、具体介绍
  • 二、具体案例
    • 1.鼠标事件
    • 2.键盘事件
    • 3.窗口事件
  • 三、事件过滤器
    • 事件过滤器的工作原理
  • 总结


前言

本篇文章将带大家来学习QT中的QEvent事件,QEvent 是 Qt 框架中的一个核心类,用于处理各种事件。在 Qt 的事件处理系统中,事件是与用户交互或系统状态变化相关的信息,例如鼠标点击、键盘输入、窗口重绘等。

一、具体介绍

1.事件的种类

QEvent 是一个抽象基类,实际的事件类型通过继承 QEvent 创建。例如,QMouseEvent、QKeyEvent、QPaintEvent 等都继承自 QEvent。
每种事件类型都有特定的功能和数据,提供对相关事件的详细信息。

2.事件的传递

Qt 使用事件循环机制来处理事件。事件从事件源(例如一个按钮)传递到事件接收者(例如一个窗口),然后根据事件类型进行处理。
事件处理过程通过事件过滤器和事件处理函数进行。你可以重写 QWidget 或 QObject 的 event 方法来处理特定的事件类型。

3.事件的分类

用户界面事件:包括鼠标事件 (QMouseEvent)、键盘事件 (QKeyEvent)、触摸事件 (QTouchEvent)。
系统事件:包括定时器事件 (QTimerEvent)、窗口事件 (QResizeEvent)、绘图事件 (QPaintEvent)。
自定义事件:你可以通过继承 QEvent 创建自定义事件,以适应应用程序的特定需求。

4.事件处理方法

重写 event 方法:在你的自定义控件类中重写 event 方法,以处理特定类型的事件。
事件过滤器:通过安装事件过滤器 (installEventFilter) 以捕获和处理未处理的事件。

二、具体案例

1.鼠标事件

#include <QApplication>
#include <QWidget>
#include <QMouseEvent>
#include <QDebug>

class MyWidget : public QWidget
{
protected:
    void mousePressEvent(QMouseEvent *event) override
    {
        qDebug() << "Mouse clicked at:" << event->pos();
    }
};

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

    MyWidget widget;
    widget.show();

    return app.exec();
}

在这里插入图片描述
在这个示例中,mousePressEvent 方法被重写以处理鼠标点击事件,每次点击时会输出点击的位置。

2.键盘事件

在 Qt 中,键盘事件用于处理用户的键盘输入。QKeyEvent 类表示键盘事件,提供了有关按键的信息,例如按下的键、键的状态等。

QKeyEvent 类
QKeyEvent 是 Qt 中用于键盘事件的类。它包含以下主要信息:

键码:按下或释放的键的编码,可以通过 key() 方法获取。
修饰符:如 Shift、Ctrl、Alt 等键的状态,通过 modifiers() 方法获取。
字符:按下键所代表的字符,通过 text() 方法获取。
事件类型:事件的类型,例如按下 (QEvent::KeyPress) 或释放 (QEvent::KeyRelease)。

主要方法
key():返回按下的键的编码。返回值为 Qt::Key 枚举类型,例如 Qt::Key_Enter、Qt::Key_A 等。
modifiers():返回当前按下的修饰键的状态,例如 Qt::ShiftModifier、Qt::ControlModifier。
text():返回与按键对应的字符。对于非字符键(如功能键),此方法可能返回空字符串。
isAutoRepeat():返回键盘事件是否为自动重复事件(例如长按键时)。

#include <QApplication>
#include <QWidget>
#include <QKeyEvent>
#include <QDebug>

class MyWidget : public QWidget
{
protected:
    void keyPressEvent(QKeyEvent *event) override
    {
        if (event->key() == Qt::Key_Escape) {
            qDebug() << "Escape key pressed!";
        } else {
            qDebug() << "Key pressed:" << event->text() << "Key code:" << event->key();
        }
    }
};

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

    MyWidget widget;
    widget.show();

    return app.exec();
}

在这里插入图片描述

3.窗口事件

窗口事件是 Qt 中处理窗口相关操作的事件类型,包括窗口大小变化、位置变化、最小化、最大化等。QResizeEvent、QMoveEvent、QCloseEvent 和 QShowEvent 是处理这些事件的主要类。

主要窗口事件类
QResizeEvent:处理窗口大小改变事件。

方法:
size():获取新的窗口大小。
oldSize():获取旧的窗口大小。
示例:在窗口大小改变时重新布局控件或调整显示内容。
QMoveEvent:处理窗口位置改变事件。

方法:
pos():获取新的窗口位置。
oldPos():获取旧的窗口位置。
示例:在窗口位置改变时更新窗口的内部状态或同步其他组件的位置。
QCloseEvent:处理窗口关闭事件。

方法:
ignore():忽略关闭事件,窗口不会关闭。
accept():接受关闭事件,窗口将关闭。
示例:在窗口关闭前显示确认对话框,询问用户是否保存更改。
QShowEvent:处理窗口显示事件。

方法:
QShowEvent 类本身不提供特定的方法,但它表示窗口被显示的事件。
示例:在窗口显示时执行初始化操作,如加载数据或设置初始状态。
QHideEvent:处理窗口隐藏事件。

方法:与 QShowEvent 类似,QHideEvent 不提供特定的方法,但它表示窗口被隐藏的事件。
示例:在窗口隐藏时保存状态或清理资源。

处理窗口关闭事件

#include <QApplication>
#include <QWidget>
#include <QCloseEvent>
#include <QMessageBox>

class MyWidget : public QWidget
{
protected:
    void closeEvent(QCloseEvent *event) override
    {
        if (QMessageBox::question(this, "Confirm", "Are you sure you want to close?") == QMessageBox::Yes) {
            event->accept();
        } else {
            event->ignore();
        }
    }
};

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

    MyWidget widget;
    widget.show();

    return app.exec();
}

在这里插入图片描述
处理窗口大小改变事件

#include <QApplication>
#include <QWidget>
#include <QResizeEvent>
#include <QDebug>

class MyWidget : public QWidget
{
protected:
    void resizeEvent(QResizeEvent *event) override
    {
        qDebug() << "Window resized from" << event->oldSize() << "to" << event->size();
    }
};

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

    MyWidget widget;
    widget.setFixedSize(300, 200);
    widget.show();

    return app.exec();
}

在这里插入图片描述

三、事件过滤器

事件过滤器是 Qt 中的一种机制,用于拦截和处理事件。通过使用事件过滤器,你可以在事件到达目标对象之前进行检查和处理,从而实现对事件的精细控制。这种机制特别有用当你希望在多个对象之间共享事件处理逻辑时。

事件过滤器的工作原理

  1. 安装事件过滤器

    • 使用 installEventFilter 方法将事件过滤器安装到一个对象上。事件过滤器本质上是一个继承自 QObject 的对象,通常重写 eventFilter 方法来实现自定义的事件处理。
  2. 事件的拦截和处理

    • 当事件发生时,它会被发送到事件过滤器的 eventFilter 方法。你可以在这个方法中决定是否处理事件、是否传递事件给目标对象,或者直接忽略事件。
  3. 返回值

    • eventFilter 方法的返回值决定了事件是否被进一步传递。如果返回 true,表示事件已经被处理,不再传递给目标对象;如果返回 false,事件将继续传递给目标对象。

示例代码

以下是一个简单的示例,演示如何使用事件过滤器来拦截和处理按钮点击事件:

#include <QApplication>
#include <QPushButton>
#include <QDebug>
#include <QEvent>

class MyEventFilter : public QObject
{
    Q_OBJECT

public:
    explicit MyEventFilter(QObject *parent = nullptr) : QObject(parent) {}

protected:
    bool eventFilter(QObject *obj, QEvent *event) override
    {
        if (event->type() == QEvent::MouseButtonPress) {
            qDebug() << "Mouse button pressed on" << obj;
            // 你可以选择返回 true 来停止事件进一步传递,或者返回 false 继续传递
            return false;
        }
        // 传递其他类型的事件
        return QObject::eventFilter(obj, event);
    }
};

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

    QPushButton button("Click Me");
    MyEventFilter *filter = new MyEventFilter();
    button.installEventFilter(filter);

    button.show();

    return app.exec();
}

#include "main.moc"

在这个示例中:

  1. MyEventFilter 继承自 QObject 并重写了 eventFilter 方法。
  2. eventFilter 方法检查事件类型,如果是鼠标按钮按下事件 (QEvent::MouseButtonPress),则输出相关信息,并选择是否继续传递事件。
  3. main 函数中,创建一个按钮并安装事件过滤器。当按钮被点击时,事件过滤器会拦截并处理鼠标按下事件。

使用场景

  1. 跨组件事件处理:可以在应用程序的不同组件之间共享事件处理逻辑。
  2. 自定义事件处理:当你需要对特定事件进行自定义处理或修改其行为时。
  3. 监控事件:用于监控应用程序中的事件流,例如记录事件日志。

总结

本篇文章就讲解到这里了,大家可以进行实践操作。

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

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

相关文章

framebuffer(帧缓冲)

framebuffer 在Linux系统中&#xff0c;Framebuffer通常是指Framebuffer设备&#xff0c;它是一种特殊的字符设备&#xff0c;在Linux系统中&#xff0c;Framebuffer设备使得程序员可以通过其设定的函数接口直接访问硬件&#xff0c;而不需要通过CPU。 framebuffer的一般操作流…

江协科技51单片机学习- p29 DS18B20温度传感器

&#x1f680;write in front&#x1f680; &#x1f50e;大家好&#xff0c;我是黄桃罐头&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流 &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd;​…

2-49 基于matlab的表面缺陷的自动分割

基于matlab的表面缺陷的自动分割。基于梯度图操作&#xff0c;对得到的梯度图进行开运算去噪&#xff0c;二值化后经过一定的形态学处理得到缺陷轮廓。通过在两个尺度上同时操作&#xff0c;高尺度的图精细&#xff0c;噪点多&#xff1b;低尺度的图粗糙&#xff0c;但包含的噪…

【人工智能】人工智能概述(二)人工智能的关键技术

文章目录 一. 机器学习与深度学习1. 机器学习2. 深度学习 二. 计算机视觉1. 基本概念和分类2. 未来计算机视觉面临的主要挑战 三. 自然语言处理1. 基本概念与分类2. 自然语言处理面临的四大挑战 四. 知识图谱1. 基本概念2. 应用场景 五. SLAM技术1. 基本概念2. 主要分类 六. 人…

Halcon 感兴趣区域

一 感兴趣区域 机器视觉中感兴趣区域是必不可少的&#xff0c;尤其是Halcon。其目的是将集中处理图像中的特定部分。此方法将区域信息与图像矩阵相结合&#xff0c;只与图像中的某些区域保持关联&#xff0c;减少图像处理的像素。使用ROI的优势&#xff1a;第一&#xff0c;减…

Redis学习[1] ——基本概念和数据类型

Redis学习[1] ——基本概念和数据类型 一、Redis基础概念 1.1 Redis是什么&#xff0c;有什么特点&#xff1f; Redis是一个基于**内存的数据库&#xff0c;因此读写速度非常快**&#xff0c;常用作缓存、消息队列、分布式锁和键值存储数据库。支持多种数据结构&#xff1a;…

网络协议二 : 使用Cisco Packet Traceer工具模拟网络环境,集线器,网桥,交换机,路由器,IP,同一网段

1. 安装 Cisco Packet Tracer baidu 网盘地址&#xff0c;感谢大神分享 安装&#xff0c;破解&#xff0c;中文化&#xff0c;都有说明&#xff0c;建议使用7.x的那个版本&#xff0c;感觉比8.x的翻译要完整一点 https://pan.baidu.com/s/18iWBOfhJJRhqgQqdNQcfMQ?pwddcch#…

【C++】实验七

题目&#xff1a; 1、自己找规律利用数组完成下列数据的输出&#xff1a; 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 思路&#xff1a;数据是斐波那契数列的前20项。该数列特点是除第一第二项以…

公交车客流统计产品介绍

在当今智能科技与交通运输融合的背景下&#xff0c;一款新型公交车客流统计产品应运而生。该系统采用先进的双目客流统计算法&#xff0c;实现多通道视频的客流数据统计&#xff0c;以其高实时性和98%的准确性在复杂环境下准确统计人数。 产品特点 双目客流统计算法 该公交车客…

Vscode报错:line too long (84 > 79 characters)

原因&#xff1a;不允许一行超过79个字母&#xff0c;但是该行代码超出该范围。 参考博客&#xff1a;解决Vs CodeFlake8 报错line too long (108 &#xff1e; 79 characters)Flake8(E501)_flake8 line too long-CSDN博客

Git安装以及配置Gitee秘钥

一、Windows环境GIt安装 1、官网下载git&#xff0c;地址&#xff1a;Git - Downloads 2、安装成功后&#xff0c;点击鼠标右键会有Git GUI Here&#xff08;图形界面&#xff09;和Git Bash Here&#xff08;命令窗口&#xff09; 3、点击Git Bash Here,分别输入以下命令&…

数据库练习4

建库使用库 修改student 表中年龄(sage)字段属性&#xff0c;数据类型由int 改变为smallint 为Course表中Cno 课程号字段设置索引,并查看索引 为SC表建立按学号(sno)和课程号(cno)组合的升序的主键索引&#xff0c;索引名为SC_INDEX 创建一视图 stu info,查询全体学生的姓名&am…

Lingo求解器百度云下载 ling 8.0/lingo 18安装包资源分享

如大家所熟悉的&#xff0c;Lingo是Linear Interaction and General Optimizer的缩写&#xff0c;中文名称为“交互式线性和通用优化求解器”&#xff0c;是一套专门用于求解最优化问题的软件包。 在大部分人认知里&#xff0c;Lingo可用于求解线性规划、二次规划、整数规划、…

【中项】系统集成项目管理工程师-第7章 软硬件系统集成-7.3软件集成

前言&#xff1a;系统集成项目管理工程师专业&#xff0c;现分享一些教材知识点。觉得文章还不错的喜欢点赞收藏的同时帮忙点点关注。 软考同样是国家人社部和工信部组织的国家级考试&#xff0c;全称为“全国计算机与软件专业技术资格&#xff08;水平&#xff09;考试”&…

交通数据处理-计算途径某些路段的车辆数

根据车辆的运行轨迹&#xff0c;计算先经过某些路段&#xff0c;再经过某些路段的车辆数。 欢迎关注本人公众号--交通数据探索师 如下表&#xff0c; 其中&#xff1a;vehicle: 车辆编号&#xff1b;route: 车辆轨迹。 以第一行为例&#xff0c;车辆car1按顺序经过了路段123…

从0开始搭建vue + flask 旅游景点数据分析系统(三):开发header部分

这一期开始开发header部分&#xff0c;预期实现两个目标&#xff1a; 右侧显示用户名、退出按钮和头像左侧显示系统的访问的路径 1 修改Layout.vue 先修改el-header部分, <el-header class"header"> <!-- <div class"logo">My Ad…

【leetcode 详解】生成特殊数字的最少操作【中等】(C++思路精析)

题目见下&#xff1a; 测试数据: 解题思路笔记&#xff1a; 最初拿到这道题是很蒙的&#xff0c;联想不到什么数据结构的模型&#xff08;肯定是笔者积累太少了&#xff09;&#xff0c;甚至惯性地想怎么实现“删除数字”的操作&#xff1a;在原字符串中抽出一个字符然后将剩…

趋动科技与天数智芯携手构筑全场景高效算力底座

近日&#xff0c;趋动科技与天数智芯正式推出联合解决方案&#xff0c;该方案基于趋动科技OrionX AI算力资源池化软件以及天数智芯通用GPU产品构建AI算力资源池&#xff0c;实现异构算力资源的统一纳管。 经测试&#xff0c;OrionX AI算力资源池化软件与天数智芯通用GPU产品相…

数据结构·红黑树

1. 红黑树的概念 红黑树&#xff0c;是一种搜索二叉树&#xff0c;但在每个节点上增加一个存储位表示节点的颜色&#xff0c;可以是Red或Black。通过对任意一条从根到叶子的路径上各个节点着色方式的限制&#xff0c;红黑树确保没有一条路径会比其他路径长出两倍&#xff0c;因…

【C++11】C++11新纪元:深入探索右值引用与移动语义

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ ⏩收录专栏⏪&#xff1a;C “ 登神长阶 ” &#x1f921;往期回顾&#x1f921;&#xff1a;位图与布隆过滤器 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀C11 &#x1f4d2;1. C11简介…