QT--事件(丰富操作,高级功能)

news2024/9/19 7:36:17

一、事件

1.事件与信号的区别
  • 事件来自外部,是随机发生的。信号来自内部,是主动发生的。有点像外中断和内中断的区别。
  • 事件:适用于处理系统级别的输入和状态变化,种类繁多,能够应对复杂的交互需求。
  • 信号/槽:适用于对象间通信和状态变化响应,灵活性高,支持异步通信和多线程编程。
  • 信号是单调的,而事件是丰富的。
2.事件系统QEvent
  • GUI(Graphical User Interface) 应用程序是由事件(event)驱动的,点击鼠标、按下某个按键、改变窗口大小、最小化窗口等都会产生相应的事件,应用程序对这些事件进行相应的处理以实现程序的功能。
  • 在大多数情况下,GUI进程和UI进程这两个术语是可以互换使用的,它们通常指的是同一个概念,即处理和管理图形用户界面(Graphical User Interface, GUI)以及用户与应用程序交互的进程。
  • 代码详解
#include "widget.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
//QApplication类是Qt应用程序的核心,负责管理应用程序的控制流和主要设置。
通过构造函数QApplication::QApplication(int &argc, char **argv)创建
一个QApplication对象。这个对象初始化应用程序的环境,并且启动事件循环。


    Widget w;
    w.show();
//Widget w;创建一个名为w的Widget对象(假设Widget是自定义的窗口类,继承自QWidget或其子类)。
w.show();调用QWidget的show()方法,使窗口显示在屏幕上。显示窗口后,QWidget开始接收和处理事件。



    return a.exec();
 //a.exec()启动Qt的主事件循环。这是一个阻塞调用,直到应用程序退出(通常是通过调用QApplication::quit()或窗口关闭事件)。
在事件循环中,QApplication会持续监控事件队列,等待并处理各种事件,如鼠标点击、键盘输入、窗口重绘请求等。
}

3. 事件过滤器
  • 事件过滤器。它可以将一个对象的事件委托给另一个对象来监视并处理。例如,一个窗口可以作为其界面上的QLabel组件的事件过滤器,派发给QLabel 组件的事件由窗口去处理,这样,就不需要为了处理某种事件而新定义一个标签类。
  • 要实现事件过滤器功能,需要完成两项操作。
    - 被监视对象使用函数installEventFilter()将自己注册给监视对象,监视对象就是事件过滤器。
    - 监视对象重新实现函数eventFilter(),对监视到的事件进行处理。作为事件过滤器的监视对象需要重新实现函数eventFilter()
  • 事件过滤器可以在事件到达目标对象之前进行预处理,从而提供了更多的控制和灵活性。
  • 主要作用和使用场景
    1. 事件拦截和预处理
    - 检查修改事件:在事件到达目标对象之前检查和修改事件。例如,可以在事件到达目标对象之前记录事件信息、修改事件数据或阻止事件的进一步传播。
    - 实现自定义逻辑:在事件到达目标对象之前实现自定义逻辑。例如,可以在鼠标点击之前判断是否允许特定操作,或者在键盘输入之前进行输入验证。
    2. 统一处理多个对象的事件
    - 事件过滤器允许你统一处理多个对象的事件,而不需要在每个对象上实现事件处理函数。这对于管理复杂界面中的多个控件特别有用。
    - 集中处理事件:将事件处理逻辑集中到一个地方(即事件过滤器),而不是在每个控件的事件处理函数中实现。
    - 简化代码:减少代码重复,使代码更清晰、易于维护。
    3. 实现复杂的事件处理逻辑
    - 拦截阻止事件:根据需要阻止事件的进一步传播。例如,可以阻止鼠标事件在控件之间传播,或者阻止特定的键盘输入。
    - 实现全局事件处理:在整个应用程序中实现全局事件处理逻辑,例如处理所有控件的鼠标点击事件。
    4. 使用场景
    - 自定义控件行为:修改控件的默认行为,例如在按钮上添加额外的点击处理逻辑。
    - 事件监控:记录或调试事件,例如记录所有鼠标点击事件的位置和类型。
    - 跨控件事件处理:在一个地方集中处理多个控件的事件,例如处理所有按钮的点击事件。
4. 代码举例
//widget.h
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget> // 包含QWidget类的定义

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; } // 声明Qt UI命名空间
QT_END_NAMESPACE

// Widget类定义,继承自QWidget
class Widget : public QWidget
{
    Q_OBJECT // Qt的Meta-Object系统宏,用于支持信号和槽机制

public:
    // 构造函数,接受一个可选的父窗口指针
    Widget(QWidget *parent = nullptr);
    
    // 析构函数
    ~Widget();

    // 事件过滤器重写函数
    // 用于拦截并处理对象的事件
    bool eventFilter(QObject *watched, QEvent *event) override;

public slots:
//信号槽函数
    void btnClickedSlotFun();


private:
    // UI指针,指向自动生成的UI类
    Ui::Widget *ui;
};

#endif // WIDGET_H

//widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QMouseEvent>

Widget::Widget(QWidget *parent)
    : QWidget(parent)         // 调用基类QWidget的构造函数
    , ui(new Ui::Widget)      // 初始化UI指针
{
    ui->setupUi(this);        // 设置UI组件

    // 安装事件过滤器到不同的UI组件
    ui->label->installEventFilter(this);     // 监控ui->label的事件
    ui->btn->installEventFilter(this);       // 监控ui->btn的事件
    ui->labHover->installEventFilter(this);  // 监控ui->labHover的事件
    ui->labDBClick->installEventFilter(this); // 监控ui->labDBClick的事件
    connect(ui->btn,SIGNAL(clicked()),this,SLOT(btnClickedSlotFun()));
}

Widget::~Widget()
{
    delete ui;   // 释放UI指针的内存
}

bool Widget::eventFilter(QObject *watched, QEvent *event)
{
    // 处理ui->label的事件
    if (watched == ui->label) {
        if (event->type() == QEvent::MouseButtonPress) {
            QMouseEvent *ev = static_cast<QMouseEvent *>(event); // 转换为QMouseEvent类型
            qDebug() << "label press" << ev->button() << "x=" << ev->x() << "y=" << ev->y(); // 输出鼠标点击信息
        } else if (event->type() == QEvent::Enter) {
            qDebug() << "label enter"; // 输出鼠标进入事件
        } else if (event->type() == QEvent::Leave) {
            qDebug() << "label leave"; // 输出鼠标离开事件
        }
    }

    // 处理ui->btn的事件
    else if (watched == ui->btn) {
        if (event->type() == QEvent::Enter) {
            static int a = 1; // 用于更新计数器
            ui->lineEdit->setText(QString("zhangsan = %1").arg(a++)); // 更新lineEdit的文本
            qDebug() << "btn enter"; // 输出鼠标进入事件
        } else if (event->type() == QEvent::Leave) {
            qDebug() << "btn leave"; // 输出鼠标离开事件
        }
    }

    // 处理ui->labHover的事件
    else if (watched == ui->labHover) {
        if (event->type() == QEvent::Enter) {
            ui->labHover->setStyleSheet("background-color: rgb(170, 255, 255);"); // 鼠标进入时改变背景颜色
        } else if (event->type() == QEvent::Leave) {
            ui->labHover->setStyleSheet(""); // 鼠标离开时恢复背景颜色
            ui->labHover->setText("靠近我,点击我"); // 恢复标签文本
        } else if (event->type() == QEvent::MouseButtonPress) {
            ui->labHover->setText("button pressed"); // 鼠标按下时更新标签文本
        } else if (event->type() == QEvent::MouseButtonRelease) {
            ui->labHover->setText("button released"); // 鼠标释放时更新标签文本
        }
    }

    // 处理ui->labDBClick的事件
    else if (watched == ui->labDBClick) {
        if (event->type() == QEvent::Enter) {
            ui->labDBClick->setStyleSheet("background-color: rgb(85, 255, 127);"); // 鼠标进入时改变背景颜色
        } else if (event->type() == QEvent::Leave) {
            ui->labDBClick->setStyleSheet(""); // 鼠标离开时恢复背景颜色
            ui->labDBClick->setText("可双击的标签"); // 恢复标签文本
        } else if (event->type() == QEvent::MouseButtonDblClick) {
            ui->labDBClick->setText("double clicked"); // 鼠标双击时更新标签文本
        }
    }

    // 调用基类的eventFilter方法,允许事件继续传播
    return QWidget::eventFilter(watched, event);
}

void Widget::btnClickedSlotFun()
{
    static int c = 1;
    qDebug()<<"c = "<<c;
}


在这里插入图片描述

5. QT事件类型

Qt事件类型

事件类事件类型事件描述
QMouseEventQEvent::MouseButtonDblClick鼠标双击
QEvent::MouseButtonPress鼠标按键按下,可以是左键或右键
QEvent::MouseButtonRelease鼠标按键释放,可以是左键或右键
QEvent::MouseMove鼠标移动
QWheelEventQEvent::Wheel鼠标滚轮滚动
QHoverEventQEvent::HoverEnter鼠标光标移动到组件上方并悬停(hover)
QEvent::HoverLeave鼠标光标离开某个组件上方
QEvent::HoverMove鼠标光标在组件上方移动
QEnterEventQEvent::Enter鼠标光标进入组件或窗口边界范围内
QEventQEvent::Leave鼠标光标离开组件或窗口边界范围
QKeyEventQEvent::KeyPress键盘按键按下
QEvent::KeyRelease键盘按键释放
QFocusEventQEvent::FocusIn组件或窗口获得键盘的输入焦点
QEvent::FocusOut组件或窗口失去键盘的输入焦点
QEvent::FocusAboutToChange组件或窗口的键盘输入焦点即将变化
QShowEventQEvent::Show窗口在屏幕上显示出来,或组件变得可见
QHideEventQEvent::Hide窗口在屏幕上隐藏(例如窗口最小化),或组件变得不可见
QMoveEventQEvent::Move组件或窗口的位置移动
QCloseEventQEvent::Close窗口被关闭,或组件被关闭,例如QTabWidget的一个页面被关闭
QPaintEventQEvent::Paint界面组件需要更新重绘
QResizeEventQEvent::Resize窗口或组件改变大小
QStatusTipEventQEvent::StatusTip请求显示组件的statusTip信息
QHelpEventQEvent::ToolTip请求显示组件的toolTip信息
QEvent::WhatsThis请求显示组件的whatsThis信息
QDragEnterEventQEvent::DragEnter在拖放操作中,鼠标光标移动到组件上方
QDragLeaveEventQEvent::DragLeave在拖放操作中,鼠标光标离开了组件
QDragMoveEventQEvent::DragMove拖放操作正在移动过程中
QDropEventQEvent::Drop拖放操作完成,即放下拖动的对象
QTouchEventQEvent::TouchBegin开始一个触屏事件序列(sequence)
QEvent::TouchCancel取消一个触屏事件序列
QEvent::TouchEnd结束一个触屏事件序列
QEvent::TouchUpdate触屏事件
QGestureEventQEvent::Gesture手势事件,能识别的手势有轻触、放大、扫屏等
QNativeGestureEventQEvent::NativeGesture操作系统检测到手势而产生的事件
QActionEventQEvent::ActionAdded运行QWidget::addAction()函数时会产生这种事件
QEvent::ActionChangedAction改变时触发的事件
QEvent::ActionRemoved移除Action时触发的事件

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

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

相关文章

学习并测试SqlSugar的单库事务功能

SqlSugar支持单库事务、多租户事务、多库事务&#xff0c;本文学习并测试单库事务的基本用法。   使用SqlSugarClient类、ISqlSugarClient接口都可以创建SqlSugarClient数据库操作实例&#xff0c;其区别在于&#xff0c;针对单库而言&#xff0c;SqlSugarClient类支持调用Be…

硬件开发笔记(二十七):AD21导入DC座子原理图库、封装库,然后单独下载其3D模型融合为3D封装

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/140541464 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV…

睿考网:2024年城乡规划师考试时间

2024年城乡规划师报名时间已经结束&#xff0c;考试时间以及考试科目为&#xff1a; 2024年9月7日&#xff1a; 9.00-11.30&#xff0c;城乡规划原理(客观题) 14.00-16.30&#xff0c;城乡规划相关知识(客观题) 2024年9月8日&#xff1a; 9.00-11.30&#xff0c;城乡规划管…

AV1技术学习:Intra Prediction

对于帧内预测模式编码块&#xff0c;亮度分量的预测模式和色度分量的预测模式在比特流中分别发出信号。亮度预测模式是基于相邻左侧和上侧两个编码块预测上下文的概率模型进行熵编码的。色度预测模式的熵编码取决于色度预测模式的状态。帧内预测以变换块为单位&#xff0c;并使…

PyTorch张量拼接方式【附维度拼接/叠加的数学推导】

文章目录 1、简介2、torch.cat3、torch.stack4、数学过程4.1、维度拼接4.1.1、二维张量4.1.2、三维张量4.1.3、具体实例 4.2、维度叠加4.2.1、0维叠加4.2.2、1维叠加4.2.3、2维叠加&#xff08;非常重要⭐&#xff09; &#x1f343;作者介绍&#xff1a;双非本科大三网络工程专…

Android14之调试广播实例(二百二十五)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

Linux的热插拔UDEV机制和守护进程

目录 一、Linux的热插拔UDEV机制 二、守护进程 2.1 守护进程概念和基本特点&#xff1a; 2.2 显示进程信息&#xff1a; 2.3 守护进程和后台进程的区别&#xff1a; 2.4 创建守护进程的步骤和守护进程的特征&#xff1a; 2.4.1 创建守护进程的步骤&#xff1a; 2.4.2 守…

京东Android一面凉经(2024)

京东Android一面凉经(2024) 笔者作为一名双非二本毕业7年老Android, 最近面试了不少公司, 目前已告一段落, 整理一下各家的面试问题, 打算陆续发布出来, 供有缘人参考。今天给大家带来的是《京东Android一面凉经(2024)》。 面试职位: Android开发工程师 技术一面 面试时长: 50…

Plant simulation 中快速创建相同属性轨道的方法

问题&#xff1a;默认的轨道宽度是0.3m&#xff0c;默认轨道是水平的。如果要创建大量宽度1m&#xff0c;竖着的轨道有没有效率的方法呢&#xff1f;答案肯定是有的&#xff0c;按下面方法操作即可。 1、复制两个轨道模型到用户对象中&#xff0c;命名为水平轨道和竖直轨道。 …

开源免费的一个企业级商城系统

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 系统简介 ShopXO&#xff1a; 是一款企业级免费开源商城系统&#xff0c;具备可视化DIY拖拽装修功能&#xff0…

[240720] X-CMD 发布 v0.4.1:新增 OpenAI GPT-4o mini 模型|优化 df ip dns ...

目录 X-CMD 发布 v0.4.1✨ openai✨ chat✨ df✨ ip✨ kev✨ dns✨ shodan✨ pick✨ theme X-CMD 发布 v0.4.1 ✨ openai 更新 X-CMD 现已支持 OpenAI 最新模型 GPT-4o mini&#xff01; &#x1f389; 用户只需使用 gpt4om 即可直接调用这款强大的模型。gpt 的默认模型由 g…

PyTorch张量数值计算

文章目录 1、张量基本运算2、阿达玛积3、点积运算4、指定运算设备⭐5、解决在GPU运行PyTorch的问题 &#x1f343;作者介绍&#xff1a;双非本科大三网络工程专业在读&#xff0c;阿里云专家博主&#xff0c;专注于Java领域学习&#xff0c;擅长web应用开发、数据结构和算法&am…

计算机的错误计算(三十二)

摘要 在计算机的错误计算&#xff08;二十八&#xff09;与&#xff08;三十 一&#xff09;中&#xff0c;我们探讨了 Visual Studio 对 6个随机exp(x)函数的计算精度问题。根据网友的反馈&#xff0c;本节将展示 Python 对它们的输出&#xff1a;结果几乎与 Visual Studio …

C# —— CRC16 算法

CRC16:即循环冗余校验码。数据通信当中一种常用的查错校验码 其特征信息字段和校验字段的长度可以是任意选定的&#xff0c;对数据进行指定多项式计算 并且将得到的结果附加在帧的后面&#xff0c;接受的设备也执行类似的算法&#xff0c;以保证数据传输的正确性和完整性 crc…

ELK日志收集

一、什么是ELK ELK 是由 Elasticsearch、Logstash、Kibana 三个开源软件的组成的一个组合体&#xff0c;ELK 是 elastic 公司研发的一套完整的日志收集、分析和展示的企业级解决方案。 ELK 的好处&#xff1a; ELK 组件在大数据运维系统中&#xff0c;主要可解决的问题如下&…

录取查询老师在哪里制作?

随着考试的落幕&#xff0c;家长们焦急等待的心情终于可以稍微缓解&#xff0c;因为录取结果即将揭晓。然而&#xff0c;对于老师来说&#xff0c;这仅仅是另一项繁重工作的开始。他们需要将每一份录取通知单逐一发送给学生家长&#xff0c;这个过程不仅耗时而且容易出错。面对…

基于SSM的高考志愿选择辅助系统

基于SSM的高考志愿选择辅助系统的设计与实现~ 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringSpringMVCMyBatis工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 前台 前台首页 院校展示 后台 后台首页 学校管理 摘要 随着高考制度的不断完…

数据结构 day4

目录 思维导图&#xff1a; 学习内容&#xff1a; 1. 链表的引入 1.1 顺序表的优缺点 1.1.1 优点 1.1.2 不足 1.1.3 缺点 1.2 链表的概念 1.2.1 链式存储的线性表叫做链表 1.2.2 链表的基础概念 1.3 链表的分类 2. 单向链表 2.1 节点结构体类型 2.2 创建链表 2.…

C语言 ——— 浮点数类型 在 内存中 的 存储模式

目录 浮点数存储规则 单\双精度浮点数 存储 S、M、E 的布局 有效数字M 和 指数位E 的特殊规定 浮点数在内存中是否存储的S、M、E 浮点数存储规则 根据国际标准IEEE754&#xff08;电气和电子工程协会&#xff09;规定&#xff1a;任意一个 浮点数F的二进制 都可以表示成…

19集 两款ESP32开发板如何选择?-《MCU嵌入式AI开发笔记》

19集 两款ESP32开发板我们用哪款&#xff1f;-《MCU嵌入式AI开发笔记》 有两款ESP32的开发板分别是ESP32 S3 和C3的&#xff0c;我们该如何选择&#xff1f; 1、ESP32-S3-BOX-3 在乐鑫官网上&#xff0c;https://www.espressif.com.cn/zh-hans/products/devkits 有ESP32S3 B…