4. QT中的鼠标键盘事件 --- 鼠标拖拽案例

1. 说明

在QT的控件或者窗口当中,如果对于当前鼠标或者键盘的功能需要自己定义,可以重写父类当中对应虚函数,主要包括以下几个:

//键盘按键按下
virtual void keyPressEvent(QKeyEvent *event);
//键盘按键抬起
virtual void keyReleaseEvent(QKeyEvent *event);
//鼠标离开
virtual void leaveEvent(QEvent *event);
//鼠标双击
virtual void mouseDoubleClickEvent(QMouseEvent *event);
//鼠标移动
virtual void mouseMoveEvent(QMouseEvent *event);
//鼠标按下
virtual void mousePressEvent(QMouseEvent *event);
//鼠标抬起
virtual void mouseReleaseEvent(QMouseEvent *event);
//鼠标滚轮事件
virtual void wheelEvent(QWheelEvent *event);

2. 相关代码

使用鼠标移动时,需要在构造函数中开启鼠标追踪

this->setMouseTracking(true);

键盘响应代码:

void Widget::keyPressEvent(QKeyEvent *event)
{
    switch (event->key()) {
    case Qt::Key_W:
        qDebug()<<"模型前进...";
        break;
    case Qt::Key_S:
        qDebug()<<"模型后退...";
        break;
    case Qt::Key_A:
        qDebug()<<"模型向左...";
        break;
    case Qt::Key_D:
        qDebug()<<"模型向右...";
        break;
    default:
        break;
    }
}

void Widget::keyReleaseEvent(QKeyEvent *event)
{
    switch (event->key()) {
    case Qt::Key_W:
        qDebug()<<"模型停止前进...";
        break;
    case Qt::Key_S:
        qDebug()<<"模型停止后退...";
        break;
    case Qt::Key_A:
        qDebug()<<"模型停止向左...";
        break;
    case Qt::Key_D:
        qDebug()<<"模型停止向右...";
        break;
    default:
        break;
    }
}

鼠标按键响应事件:

void Widget::enterEvent(QEvent *event)
{
    Q_UNUSED(event);
    qDebug()<<"鼠标进入...";
}

void Widget::leaveEvent(QEvent *event)
{
    Q_UNUSED(event);
    qDebug()<<"鼠标离开...";
}

void Widget::mouseDoubleClickEvent(QMouseEvent *event)
{
    //判断鼠标按键类型
    if(event->button() == Qt::LeftButton){
        qDebug()<<event->pos();
        qDebug()<<"鼠标双击...";
    }
    
}

3. 鼠标位置

QMouseEvent中有两种获取鼠标位置的函数,相关解释如下:

void Widget::mouseDoubleClickEvent(QMouseEvent *event)
{
    //判断鼠标按键类型
    if(event->button() == Qt::LeftButton){
        
        qDebug()<<event->pos();//输出的是鼠标在相对于本控件左上角的位置
        
        qDebug()<<event->globalPos();//输出的是鼠标相对于整个显示器窗口左上角的位置
        
        qDebug()<<"鼠标双击...";
    }
}

案例:鼠标拖动图片移动
相关位置计算辅助记忆:
在这里插入图片描述
在Qt中显示一张图片,是使用QLabel控件来装载QPixmap图像源,如果图片控件需要支持鼠标的拖拽移动,需要自己定义一个控件,然后重新其父类的鼠标控制相关函数。
所以,先定义一个C++的类,继承QLabel,重写其 mousePressEvent 和 mouseMoveEvent 类,相关代码如下:
ImageLabel.h:

#ifndef IMAGELABEL_H
#define IMAGELABEL_H

#include <QObject>
#include <QLabel>
#include <QWidget>
#include <QPixmap>

class ImageLabel : public QLabel
{
    Q_OBJECT
public:
    explicit ImageLabel(const QPixmap &pix,QWidget* parent = nullptr);

    //重写虚函数
    virtual void mousePressEvent(QMouseEvent* event) override;
    virtual void mouseMoveEvent(QMouseEvent* event) override;
    //重写键盘控制函数
    virtual void keyPressEvent(QKeyEvent* event) override;

private:
    QPoint mousePressPos;//鼠标点击位置
    int mSpeed;//控制移动速度
	
signals:

};

#endif // IMAGELABEL_H

ImageLabel.cpp:

#include "imagelabel.h"
#include <QMouseEvent>

ImageLabel::ImageLabel(const QPixmap &pix, QWidget *parent)
{
    //设置图像源
    this->setPixmap(pix);
    //设置父控件
    this->setParent(parent);
    //设置图像比例填充
    this->setScaledContents(true);
    this->mSpeed = 10;
    //处理键盘事件需要先获取焦点
    this->setFocusPolicy(Qt::StrongFocus);
}

void ImageLabel::mousePressEvent(QMouseEvent *event)
{
    //记录鼠标开始点击时的初始位置向量
    mousePressPos = event->pos();
}

void ImageLabel::mouseMoveEvent(QMouseEvent *event)
{
    //求鼠标移动偏移量(向量)
    QPoint deltaMove = event->pos() - mousePressPos;
    //此时鼠标移动了,但是控件本身位置还没有加上偏移量,还未移动
    //求窗口新位置(当前位置 + 偏移量)
    this->move(this->pos() + deltaMove);
}
void ImageLabel::keyPressEvent(QKeyEvent *event)
{
    qDebug()<<"123";
    switch (event->key()) {
        case Qt::Key_W:{
            QPoint pos = this->pos() + QPoint(0,-1) * mSpeed;
            this->move(pos);
            break;
        }
        case Qt::Key_S:{
            QPoint pos = this->pos() + QPoint(0,1) * mSpeed;
            this->move(pos);
            break;
        }
        case Qt::Key_A:{
            QPoint pos = this->pos() + QPoint(-1,0) * mSpeed;
            this->move(pos);
            break;
        }
        case Qt::Key_D:{
            QPoint pos = this->pos() + QPoint(1,0) * mSpeed;
            this->move(pos);
            break;
        }
    }

}

然后再在主窗口中使用自定义类创建图片控件即可:

//使用label在窗口上添加一个图片
QPixmap piximg(":/imgs/images/tt.png");
ImageLabel *imgLab = new ImageLabel(piximg,this);
imgLab->move(50,100);//定义初始位置

效果展示:

鼠标键盘移动自定义控件

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

linux 常用命令awk

AWK 是一种处理文本文件的语言&#xff0c;是一个强大的文本分析工具。之所以叫 AWK 是因为其取了三位创始人 Alfred Aho&#xff0c;Peter Weinberger, 和 Brian Kernighan 的 Family Name 的首字符。 AWK用法 awk 用法&#xff1a;awk pattern {action} files 1.RS, ORS, F…

【c语言】组件化打包—静态库lib

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; &#x1f525;c语言系列专栏&#xff1a;c语言之路重点知识整合 &#x…

CVE-2023-32233 Linux kernel

0x01 漏洞介绍 近日&#xff0c;研究人员发现了Linux内核的NetFilter框架中的新漏洞&#xff08;CVE-2023-32233&#xff09;。该漏洞可被本地用户用于将权限提升为root&#xff0c;并完全控制系统。问题的根源在于tfilter nf_tables是如何处理批处理请求的&#xff0c;经过身…

AutoSizer.exe:自动调整窗口大小的便捷工具

AutoSizer.exe是一款实用的桌面应用程序,它旨在帮助用户自动调整窗口大小,提供更好的用户体验。无论您是在使用Windows操作系统进行日常工作还是进行多任务处理,AutoSizer.exe可以简化您的工作流程,提高效率。本文将介绍AutoSizer.exe的下载地址、功能介绍、使用方法以及其…

为世界第一大癌症高效研发首创新药,AI大模型助力药物研发叩开未来之门

近日&#xff0c;三位高中生引爆了医药圈&#xff0c;他们使用人工智能&#xff08;AI&#xff09;引擎进行靶点发现&#xff0c;确定了多形性胶质母细胞瘤&#xff08;GBM&#xff09;的新治疗靶点&#xff0c;多形性胶质母细胞瘤&#xff08;GBM&#xff09;是最具侵袭性和最…

238:vue+openlayers绘制扩展,弓形、曲线、扇形、双箭头、进攻方向...

第238个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+openlayers中利用ol-plot插件进行绘制图形扩展,可以绘制弓形、弧形、标志旗、战斗进攻图形等等。 直接复制下面的 vue+openlayers源代码,操作2分钟即可运行实现效果; 注意如果OpenStreetMap无法加载,请加载其他…

【Shell脚本】Linux安装Nginx以及开机自启

目录 一、Linux安装Nginx脚本1、把编写好的安装Nginx脚本放置到nginx.sh文件中2、在检查网络的时候&#xff0c;这里的IP地址&#xff0c;填写的需要安装Nginx服务器的IP地址3、这里的端口号可按照自己的需要进行修改4、安装Nginx脚本 二、Nginx开机自启 一、Linux安装Nginx脚本…

Spring【Again】——复杂POJO的绑定

简单介绍&#xff1a; Again系列是将之前的内容我认为做的不好的地方或者是理解不到位的地方再来一次&#xff0c;加深记忆或者改错。我们就在来复习一下之前我们说过的复杂类型的数据绑定。 先来复习一下简单数据绑定&#xff1a; 简单数据绑定就是我们在传递参数的时候&am…

玩转ChatGPT:快速制作PPT

一、写在前面 首先还是让小Chat推销下自己&#xff1a; 你是否曾经为制作 PPT 而烦恼&#xff1f;现在有了 ChatGPT&#xff0c;再也不必担心灵感枯竭啦&#xff01;使用 ChatGPT 撰写 PPT 可以让你轻松地组织思路、快速得到内容&#xff0c;无需任何营销口号&#xff0c;Cha…

C++模板类与继承

目录 分类 一、模板类不继承 &#xff08;1&#xff09;代码 &#xff08;2&#xff09;分析 &#xff08;3&#xff09;运行结果 二、模板类继承普通类 &#xff08;1&#xff09;代码 &#xff08;2&#xff09;分析 &#xff08;3&#xff09;运行结果 三、普通类继…

Win11校园网不弹出登录页面怎么回事?

Win11校园网不弹出登录页面怎么回事&#xff1f;最近有用户在使用校园网的时候遇到了一些问题&#xff0c;访问登录网站的时候&#xff0c;一直无法显示登录的界面。那么遇到这个情况如何去进行解决呢&#xff1f;一起来看看以下的解决方法分享吧。 解决方法如下&#xff1a; 方…

nodejs处理xlsx文件生成json文件

nodejs处理xlsx文件有好几种方式&#xff0c;这里用的是js-xlsx库&#xff1b; 需求 有一个 xlsx 的文件&#xff0c;里面有几个不同的 sheet&#xff0c;需要读取这个表格中不同 sheet 的数据&#xff0c;并且为每个 sheet 生成对应的 json 文件。 例如有一个名为 template…

文本三剑客之——Awk

Awk Awk简介Awk语法格式Awk常见内置变量Awk实例演示按行输出文本BEGIN模式和END模式按字段输出文本通过管道&#xff0c;双引号调用shell命令date 的用法getline的用法awk数组 Awk简介 Awk是一个功能强大的编辑工具&#xff0c;用于在Linux/UNIX 下对文本和数据进行处理。数据…

ChatGPT vs. Bing vs. Bard

随着 2022 年 ChatGTP 的推出&#xff0c;人工智能聊天机器人的世界突然走上了一条新道路。如今&#xff0c;密切关注 AI 的人都知道&#xff0c;不同公司推出了几款产品。从谷歌拥有自己的 Bard AI&#xff0c;到微软发布新的 Bing AI Chat&#xff0c;再到 OpenAI 发布GPT-4。…

用gost实现远程端口映射

gost 是一个非常优秀的tunnel. 支持多种形式的端口映射。 本文只介绍远程端口映射方式的tunnel. 远程端口映射的意思就是&#xff0c;将本地端的某个服务的端口A&#xff08;tcp/udp&#xff09;映射到远程的某个端口P上&#xff0c; 用户通过访问远程的端口P来访问本地端的这…

生态碳汇涡度通量数据分析

生态碳汇涡度相关监测与通量数据分析 朱老师&#xff08;副教授&#xff09;&#xff1a;来自国内重点高校&#xff0c;长期从事涡度通量观测与分析研究&#xff0c;发表SCI论文多篇&#xff0c;主持国家与地方科研项目多个&#xff0c;在生态环境数据处理与分析中具有丰富的实…

Fourier分析入门——第3章——离散函数的Fourier分析

目录 第 3 章 离散函数的Fourier分析 3.1 引言 3.2 在1点采样的函数 3.3 在2点采样的函数 3.4 Fourier分析是一种线性变换 3.5 Fourier分析是一种基向量的变更 3.6 在3点采样的函数 3.7 在D点采样的函数 3.8 整理(tidying up) 3.9 Parseval[p:zeifa:l]定理 3.10 关联…

【LeetCode】203,移除链表元素。 难度等级:简单。链表入门题目,值得深入研究。

文章目录 一、题目二、解答&#xff1a;迭代法&#xff0c;引入一个新的头结点三、难点解释 【LeetCode】203&#xff0c;移除链表元素。 难度等级&#xff1a;简单。 本题是链表入门题目&#xff0c;值得深入研究。 一、题目 二、解答&#xff1a;迭代法&#xff0c;引入一个…

Spring实现IOC和DI入门案例(XML版)

文章目录 1 IOC入门案例(XML版)1.1 思路分析1.2 代码实现步骤1:创建Maven项目步骤2:添加Spring的依赖jar包步骤3:添加案例中需要的类步骤4:添加spring配置文件步骤5:在配置文件中完成bean的配置步骤6:获取IOC容器步骤7:从容器中获取对象进行方法调用步骤8:运行程序 2 DI入门案例…

【差分+操作】C. Helping the Nature

Problem - 1700C - Codeforces 题意&#xff1a; 思路&#xff1a; 一开始手玩了一下 如果不是高低高的形式&#xff0c;那么一定不能通过操作3把全部元素变成0 因此就是先把所有元素变成高低高的形式 但是低在什么地方不确定 因此考虑枚举中间低谷位置&#xff0c;O(1)计…