【QT】鼠标按键事件 - QMouseEvent QKeyEvent

qt 事件

  • 事件
    • 1. 事件概念
    • 2. 事件的处理
    • 3. 按键事件
      • (1)单个按键
      • (2)组合按键
    • 4. 鼠标事件
      • (1)鼠标单击事件
      • (2)鼠标释放事件
      • (3)鼠标双击事件
      • (4)鼠标移动事件
      • (5)滚轮事件

事件

1. 事件概念

事件是应用程序内部或者外部产生的事情或者动作的统称。在 Qt 中使用⼀个对象来表⽰⼀个事件。所有的 Qt 事件均继承于抽象类 QEvent。事件是由系统或者 Qt 平台本⾝在不同的时刻发出的。当用户按下⿏标、敲下键盘,或者是窗⼝需要重新绘制的时候,都会发出⼀个相应的事件。⼀些事件是在用户操作时发出,如键盘事件、⿏标事件等,另⼀些事件则是由系统本⾝⾃动发出,如定时器事件。常见的 Qt 事件如下:

在这里插入图片描述

常见事件描述:

在这里插入图片描述

2. 事件的处理

事件处理⼀般常用的方法为:重写相关的 Event 函数。

在 Qt 中,几乎所有的 Event 函数都是虚函数,所以可以重新实现。如:在实现⿏标的进⼊和离开事件时,直接重新实现 enterEvent() 和 leaveEvent() 即可。enterEvent()leaveEvent() 函数原型如下:

在这里插入图片描述

代码示例1:

1、新建 Qt 项目,基类选择 QWidget,同时勾选 UI 界面文件;
2、设计 UI 文件,在 ui 文件中拖入一个 Label,给 Label 加一个边界框,方便观察鼠标进入和移动,如下图;

在这里插入图片描述

3、在项目中新添加⼀个类:MyLabel;

先选中项⽬名称 qt_event,点击⿏标右键,选择 add new … ,弹出如下对话框:

在这里插入图片描述

接下来弹出以下界面,按照下面的操作即可:

在这里插入图片描述

此时项⽬中会新添加以下两个文件件:

在这里插入图片描述

4、将 enterEvent() 添加到项目文件 “mylabel.h” 中:

			#ifndef MYLABEL_H#define MYLABEL_H#include <QWidget>class MyLabel : public QWidget{Q_OBJECTpublic:explicit MyLabel(QWidget *parent = nullptr);// 鼠标进入事件void enterEvent(QEvent* event);signals:};#endif // MYLABEL_H

5、在 mylabel.cpp 中重写 enterEvent() 方法:

			#include "mylabel.h"#include <QDebug>MyLabel::MyLabel(QWidget *parent) : QWidget(parent){}void MyLabel::enterEvent(QEvent *event){qDebug() << "鼠标进入事件";}

6、在 UI 文件中选中 Label,右键 ------> 提升为…,当点击 "提升为… " 之后,弹出如下对话框,按照顺序添加即可:

在这里插入图片描述

7、修改基类,到 mylabel.cpp 和 mylabel.h 中将 Widget 改为 QLabel:

mylabel.h:

			#ifndef MYLABEL_H#define MYLABEL_H#include <QLabel>class MyLabel : public QLabel{Q_OBJECTpublic:explicit MyLabel(QWidget *parent = nullptr);// 鼠标进入事件void enterEvent(QEvent* event);signals:};#endif // MYLABEL_H

mylabel.cpp:

			#include "mylabel.h"#include <QDebug>MyLabel::MyLabel(QWidget *parent) : QLabel(parent){}void MyLabel::enterEvent(QEvent *event){qDebug() << "鼠标进入事件";}

8、执行效果如下:当⿏标进⼊设计好的标签之后,就会在应⽤程序输出栏中打印:⿏标进⼊:

在这里插入图片描述

代码示例2: 当⿏标点击时,获取对应的坐标值;

1、在上述示例的基础上,在 mylabel.h 中声明 mousePressEvent() 方法:

			class MyLabel : public QLabel{Q_OBJECTpublic:explicit MyLabel(QWidget *parent = nullptr);// 鼠标进入事件void enterEvent(QEvent* event);// 鼠标移动事件void mousePressEvent(QMouseEvent* ev);signals:};

2、在 mylabel.cpp 中重写 mousePressEvent() 方法:

			#include "mylabel.h"#include <QDebug>#include <QMouseEvent>MyLabel::MyLabel(QWidget *parent) : QLabel(parent){}void MyLabel::enterEvent(QEvent *event){qDebug() << "鼠标进入事件";}void MyLabel::mousePressEvent(QMouseEvent *ev){// qt中的格式化字符串QString str1 = QString("鼠标按下了 x = %1, y = %2").arg(ev->x()).arg(ev->y());qDebug() << str1;}

实现效果如下:

在这里插入图片描述

示例代码3: ⿏标左键点击时,打印对应的坐标值,⿏标右键点击时,打印基于屏幕的坐标

			void MyLabel::mousePressEvent(QMouseEvent *ev){// 鼠标左键if(ev->button() == Qt::LeftButton) {// x, y 为基于窗口的坐标QString str = QString("鼠标左键: x = %1, y = %2").arg(ev->x()).arg(ev->y());qDebug() << str.toUtf8().data();}// 鼠标右键if(ev->button() == Qt::RightButton) {// globalX, globalY 为基于屏幕的坐标QString str = QString("鼠标左键: x = %1, y = %2").arg(ev->globalX()).arg(ev->globalY());qDebug() << str.toUtf8().data();}}

3. 按键事件

Qt 中的按键事件是通过 QKeyEvent 类来实现的。当键盘上的按键被按下或者被释放时,键盘事件便会触发。在帮助文档中查找 QKeyEvent 类,查找按键事件中所有的按键类型,在帮助文档中输⼊:Qt::Key,如下图:

在这里插入图片描述

(1)单个按键

代码示例:当某个按键被按下时,输出:某个按键被按下了;

1、新建项目,在头文件 “widget.h” 中声明虚函数 keyPressEvent();如下:

			#ifndef WIDGET_H#define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACEnamespace Ui { class Widget; }QT_END_NAMESPACEclass Widget : public QWidget{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();// 声明按键按下事件void keyPressEvent(QKeyEvent* event);private:Ui::Widget *ui;};#endif // WIDGET_H

2、在 “widget.cpp” 文件中重写 keyPressEvent() 虚函数;

			#include "widget.h"#include "ui_widget.h"#include <QKeyEvent>#include <QDebug>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget){ui->setupUi(this);}Widget::~Widget(){delete ui;}void Widget::keyPressEvent(QKeyEvent *event){if(event->key() == Qt::Key_A) {qDebug() << "A按键被按下";}}

(2)组合按键

在 Qt 助手中搜索:Qt::KeyboardModifier,如下图示:

在这里插入图片描述

Qt::KeyboardModifier 中定义了在处理键盘事件时对应的修改键。在 Qt 中,键盘事件可以与修改键一起使用,以实现⼀些复杂的交互操作。KeyboardModifier 中修改键的具体描述如下:

在这里插入图片描述

示例代码:

			void Widget::keyPressEvent(QKeyEvent *event){// 组合按键if(event->modifiers() == Qt::ControlModifier) // 判断是否按下ctrl键{if(event->key() == Qt::Key_A) {     // 判断 A 键是否按下qDebug() << "ctrl + A 被按下";}}}

4. 鼠标事件

在 Qt 中,⿏标事件是⽤ QMouseEvent 类来实现的。当在窗⼝中按下⿏标或者移动⿏标时,都会产⽣⿏标事件。

利⽤ QMouseEvent 类可以获取⿏标的哪个键被按下了以及⿏标的当前位置等信息。在 Qt 帮助⽂档中查找 QMouseEvent 类如下图⽰:

在这里插入图片描述

(1)鼠标单击事件

在 Qt 中,⿏标按下是通过虚函数 mousePressEvent() 来捕获的。 mousePressEvent() 函数原型如下:

		[virtual protected] void QWidget::mousePressEvent(QMouseEvent *event)

⿏标左右键及滚的表示如下:

		Qt::LeftButton ⿏标左键Qt::RightButton ⿏标右键Qt::MidButton ⿏标滚轮

示例代码1:

1、在 “widget.h” 头⽂件中声明⿏标按下事件;

			#ifndef WIDGET_H#define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACEnamespace Ui { class Widget; }QT_END_NAMESPACEclass Widget : public QWidget{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();// 鼠标按下事件void mousePressEvent(QMouseEvent* event);private:Ui::Widget *ui;};#endif // WIDGET_H

2、在 “widget.cpp” ⽂件中重新实现 mousePressEvent() 函数;

			#include "widget.h"#include "ui_widget.h"#include <QMouseEvent>#include <QDebug>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget){ui->setupUi(this);}Widget::~Widget(){delete ui;}void Widget::mousePressEvent(QMouseEvent *event){if(event->button() == Qt::LeftButton) {qDebug() << "鼠标左键被按下";}}

修改成当鼠标滚轮被按下才打印:

			void Widget::mousePressEvent(QMouseEvent *event){if(event->button() == Qt::MidButton) {qDebug() << "鼠标滚轮被按下";}}

(2)鼠标释放事件

⿏标释放事件是通过虚函数 mouseReleaseEvent() 来捕获的。 mouseReleaseEvent() 函数原型如下:

		[virtual protected] void QWidget::mouseReleaseEvent(QMouseEvent *event)

示例代码:

			void Widget::mouseReleaseEvent(QMouseEvent *event){if(event->button() == Qt::LeftButton) {qDebug() << "鼠标左键被释放";}}

(3)鼠标双击事件

⿏标双击事件是通过虚函数:mouseDoubleClickEvent() 来实现的。 mouseDoubleClickEvent() 函数原型如下:

		[virtual protected] void QWidget::mouseDoubleClickEvent(QMouseEvent *event)

示例代码:

		void Widget::mouseDoubleClickEvent(QMouseEvent *event){if(event->button() == Qt::LeftButton) {qDebug() << "鼠标左键被双击";}}

(4)鼠标移动事件

⿏标移动事件是通过虚函数:mouseMoveEvent() 来实现的。同时为了实时捕获⿏标位置信息,需要通过函数 setMouseTracking() 来追踪⿏标的位置。mouseMoveEvent() 函数原型如下:

		[virtual protected] void QWidget::mouseMoveEvent(QMouseEvent *event)

setMouseTracking() 函数原型如下:

		void setMouseTracking(bool enable)

说明:setMouseTracking() 函数默认是 false,需要设置为 true,才能实时捕获⿏标位置信息。否则只有当⿏标按下时才能捕获其位置信息。

示例代码:

			Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget){ui->setupUi(this);// 设置鼠标追踪状态setMouseTracking(true);}void Widget::mouseMoveEvent(QMouseEvent *event){qDebug() << "[" << event->x() << ", " << event->y() << "]";}

(5)滚轮事件

在 Qt 中,⿏标滚轮事件是通过 QWheelEvent 类来实现的。滚轮滑动的距离可以通过 delta() 函数获取。delta() 函数原型如下:

		int QGraphicsSceneWheelEvent::delta() const

其中返回值代表滚轮滑动的距离。正数表示滚轮相对于用户向前滑动,负数表示滚轮相对于用户向后滑动。

代码示例:

			#include <QWheelEvent>void Widget::wheelEvent(QWheelEvent *event){static int x = 0;x += event->delta();   // ±120if(event->delta() > 0) {qDebug() << "滚轮往前" << x;}else {qDebug() << "滚轮往后" << x;}}

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

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

相关文章

【数据分析】统计学基础及Python具体实现

各位大佬好 &#xff0c;这里是阿川的博客&#xff0c;祝您变得更强 个人主页&#xff1a;在线OJ的阿川 大佬的支持和鼓励&#xff0c;将是我成长路上最大的动力 阿川水平有限&#xff0c;如有错误&#xff0c;欢迎大佬指正 Python 初阶 Python–语言基础与由来介绍 Python–…

【Python】已解决:ERROR: Could not install packages due to an OSError: [WinError 5] 拒绝访问。: ‘e:\anaconda\in

文章目录 一、分析问题背景二、可能出错的原因三、错误代码示例四、正确代码示例五、注意事项 已解决&#xff1a;ERROR: Could not install packages due to an OSError: [WinError 5] 拒绝访问。: ‘e:\anaconda\install_root\scripts\pip.exe’ Consider using the --user o…

C语言详解(结构体)

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸各位能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎~~ &#x1f4a5;个人主页&#xff1a;小羊在奋斗 &#x1f4a5;所属专栏&#xff1a;C语言 本系列文章为个人学习笔记&#xff0c;在这里撰写成文一…

【MAVEN】如何解决“Error unmarshaling return header; nested exception is: java.io.EOFException“?

目录标题 异常现场分析解决Chat GPT出场一下增大【Build process heap size (Mbytes) 】试试&#x1f64f;增大【Maven->importing->VM options for importer】试试✅Idea的所有配置说明 异常现场 Error unmarshaling return header; nested exception is: java.io.EOFEx…

C++内存管理(区别C语言)深度对比

欢迎来到我的Blog&#xff0c;点击关注哦&#x1f495; 前言 前面已经介绍了类和对象&#xff0c;对C面向对象编程已经有了全面认识&#xff0c;接下来要学习对语言学习比较重要的是对内存的管理。 一、内存的分区 代码区&#xff1a;存放程序的机器指令&#xff0c;通常是可…

IntelliJ IDEA安装教程(超详细)

✅作者简介&#xff1a;CSDN内容合伙人、阿里云专家博主、51CTO专家博主、新星计划第三季python赛道Top1&#x1f3c6; &#x1f4c3;个人主页&#xff1a; IDEA的使用 IDEA的简单介绍IDEA的主要优势IDEA的卸载IDEA的安装第一个程序&#xff1a;HelloWorld结束语 IDEA的简单介绍…

JAVA (Springboot) i18n国际化语言配置

JAVA i18n国际化语言配置 一、简介二、功能三、Java配置国际化步骤四、Java国际化配置工具类五、Spring Boot配置六、测试 一、简介 在Java中&#xff0c;国际化&#xff08;Internationalization&#xff0c;通常简称为i18n&#xff09;是一个过程&#xff0c;它允许应用程序…

【C语言项目】实现一个通讯录,一步一步详细讲解,小白也能看

目录 设计思路 代码实现 代码改造1 代码改造2 完整代码 代码仓库 设计思路 1. 通讯录存放的信息 这个通讯录保存的信息包括&#xff1a;名字&#xff0c;年龄&#xff0c;性别&#xff0c;电话&#xff0c;住址。 2. 通讯录的功能 1. 通讯录可以存放100个人的信息。 2…

2024年 Java 面试八股文(20w字)

> &#x1f345;我是小宋&#xff0c; 一个只熬夜但不秃头的Java程序员。 > &#x1f345;关注我&#xff0c;带你**过面试,读源码**。提升简历亮点&#xff08;14个demo&#xff09; > &#x1f345;我的面试集已有12W 浏览量。 > &#x1f30f;号…

[C++] 深度剖析C_C++内存管理机制

文章目录 内存分布内存分布图解 C语言中动态内存管理方式malloc:callocrealloc C内存管理方式内置类型**自定义类型** operator new & operator deleteoperator new & operator delete函数operator newoperator delete **new T[N]** 与**delete[]** **定位new表达式(pl…

【C语言】指针由浅入深全方位详解!!!

目录 指针 野指针 二级指针 指针数组 字符指针 数组指针 数组参数&#xff0c;指针参数 函数指针 函数指针数组 回调函数 练习题 代码仓库 指针 1. 指针定义 1. 指针是内存中一个最小单元的编号&#xff0c;也就是地址。 2. 平时口语中说的指针&#xff…

【C++】如何巧妙运用C++命名空间:初学者必备指南

C语法相关知识点可以通过点击以下链接进行学习一起加油&#xff01; 本篇将带领大家走进C的旅途&#xff0c;为了更好地学习C这门语言&#xff0c;我们需要了解它的前世今生。在了解完C如何诞生后&#xff0c;将开始我们C之旅第一站"命名空间"。(老早说是C/C博主&…

Java 集合框架:HashMap 的介绍、使用、原理与源码解析

大家好&#xff0c;我是栗筝i&#xff0c;这篇文章是我的 “栗筝i 的 Java 技术栈” 专栏的第 020 篇文章&#xff0c;在 “栗筝i 的 Java 技术栈” 这个专栏中我会持续为大家更新 Java 技术相关全套技术栈内容。专栏的主要目标是已经有一定 Java 开发经验&#xff0c;并希望进…

零基础入门转录组数据分析——GO+KEGG富集分析

零基础入门转录组数据分析——GOKEGG富集分析 目录 零基础入门转录组数据分析——GOKEGG富集分析1. 富集分析基础知识2. GO富集分析&#xff08;Rstudio&#xff09;——代码实操3. KEGG富集分析&#xff08;Rstudio&#xff09;——代码实操注&#xff1a;配套资源只要改个路径…

PyQt5| 界面设计 |利用Qt Designer实现简单界面交互

目录 1 QtDesigner简单界面设计2 代码部分2.1 ui文件转py文件2.2 界面文件代码2.3 主文件代码2.3.1 主体框架代码2.3.2 实现交互代码 3结果展示 准备工作&#xff1a; 配置好PyQt5相关的库、QtDesigner、pyuic 1 QtDesigner简单界面设计 点击“工具"——>“外部工具&a…

Matlab实现最小二乘法的几种方法

最小二乘法&#xff08;又称最小平方法&#xff09;是一种数学优化技术。它通过最小化误差的平方和寻找数据的最佳函数匹配。 按照图中所提出的问题&#xff08;如图1&#xff09;&#xff0c;要求已知多组解&#xff08;自变量和因变量&#xff09;&#xff0c;求出最佳和最恰…

【C++/STL深度剖析】priority_queue 最全解析(什么是priority_queue? priority_queue的常用接口有哪些?)

目录 一、前言 二、如何区分【优先级队列】与【队列】&#xff1f; 三、priority_queue的介绍 四、priority_queue 的构造 五、priority_queue 的常用接口 &#x1f4a7;push &#x1f4a7;pop &#x1f4a7;size &#x1f4a7;top &#x1f4a7;empty &…

C语言贪吃蛇课程设计实验报告(包含贪吃蛇项目源码)

文末有贪吃蛇代码全览,代码有十分细致的注释!!!文末有贪吃蛇代码全览,代码有十分细致的注释!!!文末有贪吃蛇代码全览,代码有十分细致的注释!!! 码文不易&#xff0c;给个免费的小星星和免费的赞吧&#xff0c;关注也行呀(⑅•͈ᴗ•͈).:*♡ 不要白嫖哇(⁍̥̥̥᷄д⁍̥̥…

【C++/STL】:vector容器的底层剖析迭代器失效隐藏的浅拷贝

目录 &#x1f4a1;前言一&#xff0c;构造函数1 . 强制编译器生成默认构造2 . 拷贝构造3. 用迭代器区间初始化4. 用n个val值构造5. initializer_list 的构造 二&#xff0c;析构函数三&#xff0c;关于迭代器四&#xff0c;有关数据个数与容量五&#xff0c;交换函数swap六&am…

SpringBoot整合Flink CDC实时同步postgresql变更数据,基于WAL日志

SpringBoot整合Flink CDC实时同步postgresql变更数据&#xff0c;基于WAL日志 一、前言二、技术介绍&#xff08;Flink CDC&#xff09;1、Flink CDC2、Postgres CDC 三、准备工作四、代码示例五、总结 一、前言 在工作中经常会遇到要实时获取数据库&#xff08;postgresql、m…