QT:键盘事件(添加资源图片)

news/2025/10/28 21:57:42/文章来源:https://www.cnblogs.com/samrv/p/19172761

键盘事件:

在图像处理和游戏应用程序中,有时需要通过键盘控制某个对象的移动,此功能可以 通过

对键盘事件的处理来实现。键盘事件的获取是通过重定义QWIDGET类的KEYPressEvent()

和KEYRELEASEEVENT()来实现的。

通过键盘的上、下、左、右方向键可以控制图标的移动,移动的步进值 为风格的大小,如果

同时按下CTRL键,则实现细微移动;若按下HOME键,则光标回到界面的左上顶点;若按下

END键,则光标到达界面的右下顶点。

image

 

image

 具体实现步骤如下

(1)头文件keyevent.h 的具体内容如下:

#ifndef KEYEVENT_H
#define KEYEVENT_H#include <QWidget>
#include <QKeyEvent>
#include <QPaintEvent>class KeyEvent : public QWidget
{Q_OBJECTpublic:KeyEvent(QWidget *parent = nullptr);~KeyEvent();void drawPix();void keyPressEvent(QKeyEvent *event) ;void paintEvent(QPaintEvent *event)  ;
private:QPixmap *pix;QImage image;int startX;int startY;int width;int height;int step;
};
#endif // KEYEVENT_H

  

(2)源文件keyevent.cpp的具体代码内容如下:

#include "keyevent.h"
#include <QPainter>KeyEvent::KeyEvent(QWidget *parent): QWidget(parent)
{setWindowTitle(tr("键盘事件"));setAutoFillBackground(true);QPalette palette = this->palette();palette.setColor(QPalette::Window,Qt::white);setPalette(palette);setMinimumSize(512,256);setMaximumSize(512,256);width =size().width();height=size().height();pix=new QPixmap(width,height);pix->fill(Qt::white);image.load("../image/image.png"); // ../ :表示EXE程序的上级目录。 ./:表示exe程序的同级目录startX=100;startY=100;step = 20;drawPix();resize(512,256);
}KeyEvent::~KeyEvent()
{
}void KeyEvent::drawPix()
{pix->fill(Qt::white);QPainter *painter = new QPainter;QPen pen(Qt::DotLine);for(int i=step; i<width;i=i+step)// 按照步进值的间隔绘制纵向的网格线{painter->begin(pix);painter->setPen(pen);painter->drawLine(QPoint(i,0),QPoint(i,height));painter->end();}for(int j=step; j<width;j=j+step) // 按照步进值的间隔绘制横向的网格线{painter->begin(pix);painter->setPen(pen);painter->drawLine(QPoint(0,j),QPoint(width,j));painter->end();}painter->begin(pix);painter->drawImage(QPoint(startX,startY),image);painter->end();
}void KeyEvent::keyPressEvent(QKeyEvent *event)
{  // 按钮 : CTRL + 方向键  的事件if(event->modifiers()==Qt::ControlModifier){if(event->key()==Qt::Key_Left){startX=(startX-1<0)?startX:startX-1;}if(event->key()==Qt::Key_Right){startX=(startX+1+image.width()>width)?startX:startX+1;}if(event->key()==Qt::Key_Up){startY=(startY-1<0)?startY:startY-1;}if(event->key()==Qt::Key_Down){startY=(startY+1+image.height()>height)?startY:startY+1;}}else{/* 首先调节图标左上顶点的位置至风格的顶点上*/startX= startX-startX%step;startY= startY-startY%step;if(event->key()==Qt::Key_Left){startX=(startX-step<0)?startX:startX-step;}if(event->key()==Qt::Key_Right){startX=(startX+step+image.width()>width)?startX:startX+step;}if(event->key()==Qt::Key_Up){startY=(startY-step<0)?startY:startY-step;}if(event->key()==Qt::Key_Down){startY=(startY+step+image.height()>height)?startY:startY+step;}if(event->key()==Qt::Key_Home){startX = 0;startY = 0;}if(event->key()==Qt::Key_End){startX= width-image.width();startY= height-image.height();}}drawPix();//根据调整后的图标位置重新在PIX中绘制图像update(); // 触发界面重画
}void KeyEvent::paintEvent(QPaintEvent *)
{QPainter painter;painter.begin(this);painter.drawPixmap(QPoint(0,0),*pix);painter.end();
}

  

(3)在项目工程所在目录(D:\QT\CH11\CH1102\KeyEvent)下新建一个文件夹并命名为image,在文件夹内保存一个名为“image.png”的图片;在项目中按照以下步骤添加资源文件。

(A)在项目名“KeyEvent”上单击鼠标右键->"添加新文件..."菜单项,在如图11.3所示的对话框中单击“Qt”模板->"Qt Resource File" ->"Choose..."按钮。

image

 (B)在弹出的对话框中选择资源要存放的路径,如图11.4所示在“名称” 栏中填写资源名称“keyevent”。单击“下一步”按钮,单击“完成”按钮。此时,项目下自动添加一个"keyevent.qrc "资源文件,如图11.5所示。

image

 

image

 图11.5 添加后的项目目录树

(C)、鼠标右击资源文件,选择“add Prefix...”菜单项,在弹出的“Add Prefix”对话框的“Prefix:”

栏中填写“/new/prifix1”,单击"oK"按钮,此时项目目录树右区资源文件下新增了一个“/new/prefix1”子目录项,单击该区下方“添加”按钮上的 "添加文件',按照如图11.6所示的步骤操作,在弹出的对话框中选项“image/image.png”文件,单击“提示”按钮,将该图片添加到项目中。

image

image

 

image

 

 

(4)drawPix()函数实现了在QPixmap对象上绘制图像,其具体代码如下:

void KeyEvent::drawPix()
{pix->fill(Qt::white);QPainter *painter = new QPainter;QPen pen(Qt::DotLine);for(int i=step; i<width;i=i+step)// 按照步进值的间隔绘制纵向的网格线{painter->begin(pix);painter->setPen(pen);painter->drawLine(QPoint(i,0),QPoint(i,height));painter->end();}for(int j=step; j<width;j=j+step) // 按照步进值的间隔绘制横向的网格线{painter->begin(pix);painter->setPen(pen);painter->drawLine(QPoint(0,j),QPoint(width,j));painter->end();}painter->begin(pix);painter->drawImage(QPoint(startX,startY),image);painter->end();
}

  

(5)keyPressEvent()函数处理键盘的按下事件,具体代码如下:

void KeyEvent::keyPressEvent(QKeyEvent *event)
{  // 按钮 : CTRL + 方向键  的事件if(event->modifiers()==Qt::ControlModifier){if(event->key()==Qt::Key_Left){startX=(startX-1<0)?startX:startX-1;}if(event->key()==Qt::Key_Right){startX=(startX+1+image.width()>width)?startX:startX+1;}if(event->key()==Qt::Key_Up){startY=(startY-1<0)?startY:startY-1;}if(event->key()==Qt::Key_Down){startY=(startY+1+image.height()>height)?startY:startY+1;}}else{/* 首先调节图标左上顶点的位置至风格的顶点上*/startX= startX-startX%step;startY= startY-startY%step;if(event->key()==Qt::Key_Left){startX=(startX-step<0)?startX:startX-step;}if(event->key()==Qt::Key_Right){startX=(startX+step+image.width()>width)?startX:startX+step;}if(event->key()==Qt::Key_Up){startY=(startY-step<0)?startY:startY-step;}if(event->key()==Qt::Key_Down){startY=(startY+step+image.height()>height)?startY:startY+step;}if(event->key()==Qt::Key_Home){startX = 0;startY = 0;}if(event->key()==Qt::Key_End){startX= width-image.width();startY= height-image.height();}}drawPix();//根据调整后的图标位置重新在PIX中绘制图像update(); // 触发界面重画
}

  

(6)界面重绘函数paintEvent(),将pix绘制在界面上。其具体代码如下:

void KeyEvent::paintEvent(QPaintEvent *)
{QPainter painter;painter.begin(this);painter.drawPixmap(QPoint(0,0),*pix);painter.end();
} 

(7)项目KEYEVENT.PRO 详细代码

QT       += core guigreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsCONFIG += c++11# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0SOURCES += \main.cpp \keyevent.cppHEADERS += \keyevent.hTRANSLATIONS += \KeyEvent_zh_CN.ts# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += targetRESOURCES += \keyevent.qrc

  

(8)运行结果如图11.2所示。

 

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

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

相关文章

2025.10.28

依旧早八一天课,晚上开会,累累的

docker desktop:更新WSL2+安装nginx

1.打开Windows系统的虚拟化(任务管理器内的CPU栏可以查看对应情况) 如果没开,查电脑型号去bios打开搜索启用或关闭Windows功能,打开下面两项 2.官网下载docker desktop,正常步骤安装,记得勾选WSL2 3.解决WSL问题…

# 学代码--看懂了但是不会写

1.1 怎么回事啊 !!! 在学习书上或者网上的代码的时候,经常会出现一种困惑:那就是初看代码,诶,我好像懂了诶。 但是要开始写的时候,就比较难下手了。我这个时候经常想:我刚刚,不是学过了吗?没学会吗哈哈哈哈…

2025-10-28 aoao Round 比赛总结

比赛链接 比赛时的状态 be like:我靠,这题怎么这么难?T1 就开始上难度了? 没一道题会写,不会要爆零然后遗憾离场了吧? (想了 2147483647 种 T1 的假做法) (去体检,在测血压时)等会,我好像想明白 T1 的本质了…

P11307 [COTS 2016] 建造费 Pristojba 分析

题目概述 这是一个 \(n\) 个点的无向图 \(G\),然后给你 \(m\) 次操作。 给你每个点的点权 \(p_i\),定义一条边 \((i,j)\) 的边权为 \(p_i+p_j\) 每个操作对应 \((x,l,r)\) 保证 \(x\notin [l,r]\)。 然后对于所有的 …

程序员如何打破职业瓶颈?先搬开这3块绊脚石。

程序员的职业路不算长,可不少人早早就遇到了 “天花板”:想提升没方向,想突破没抓手,这就是让人头疼的 “瓶颈期”。是什么让我们陷入这种困境?又该怎么走出来?咱们一点点说清楚。 摆烂心态 在程序员不算长的职业…

文件清理,推荐几款常用软件

文件清理,推荐几款常用软件给大家汇总如下表格,根据自己的情况自行选择: 您的资助是我最大的动力!金额随意,欢迎来赏!付款后有任何问题请给我留言。 如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的…

AI时代的设计师:从工具到“超人”的进化之路

最近刷到几则关于AI和设计领域的新闻,感觉挺有意思的。站酷发布了AI设计Agent,美图CEO吴欣鸿在演讲中提到AI正让设计师变成“超人”,而另一边,Meta的裁员风波又让人对AI行业的就业前景捏把汗。先说说AI工具如何改变…

MyBatis 动态 SQL 实现原理 - Higurashi

总结自(部分调整):MyBatis 3 源码深度解析SqlSource 与 BoundSql 详解 在介绍原理之前,我们首先需要了解 MyBatis 中和 SQL 语句有关的两个组件,即 SqlSource 和 BoundSql。SqlSource:代表 Java 注解或者 XML 文…

bililun

实验任务1 源代码 T.cpp#include "T.h" #include <iostream> #include <string>// 类T实现// static成员数据类外初始化 const std::string T::doc{"a simple class sample"}; const…

《程序员修炼之道:从小工到专家》观后感第二篇

《代码之美——DRY原则与简洁代码的实效哲学》 核心观点:“不要重复自己(DRY)”是编码的黄金法则,冗余代码会直接推高维护成本与bug发生率,而简洁、自解释的代码是系统可维护性的核心保障。 案例分析:某社交平台…

【学习笔记】数据结构全家桶

Data Structure前言 2025.10.28: 一时兴起建了这个,原因是刚刚学了KTT qwq 我如果塞完这个东西应该都大学几年级了吧 没事慢慢弄 正文 线段树 KTT点我展开看代码 #include<bits/stdc++.h> #define rep(i, l, r…

社区

社区报告名称:AR(Active Area Reverse)fin cut工艺参数与表征指标数据分析报告 版本:V1.0 日期:2025-09-05 编制人:李晓睿 审核人:[姓名/部门] 1. 数据收集报告 1.1 数据来源来源:AR(AA Reverse)fin cut工艺…

「Gym 102759I」Query On A Tree 17

题目大意 给定一颗 \(N\) 个节点以 \(1\) 为根的有根树,每次给以 \(u\) 为根的子树每点加 \(1\) 的值或给路径 \(u - v\) 上每点加 \(1\) 的值,每次修改后查询一个点 \(u\) 使得 \(\sum_{v = 1}^N dis(u, v)\) 最小。…

Mybatis使用简述

什么是 MyBatis? MyBatis 是一款优秀的 Java 持久层框架,它通过 XML 或注解的方式将 Java 对象与数据库中的记录进行映射。与传统的 JDBC 相比,MyBatis 极大地简化了数据库操作代码,让开发者能够更专注于业务逻辑而…

重组蛋白表达服务:CHO HEK293细胞系选择与表达优化方案

重组蛋白表达服务:CHO/HEK293细胞系选择与表达优化方案在生命科学研究领域,重组蛋白作为重要的科研试剂,其质量直接影响实验结果的可靠性。选择合适的表达系统并进行表达优化,是获得高质量重组蛋白的关键环节。本文…

C++里的代码命名规范

以下是 C++ 中最主流的几种命名规范: 1. 蛇形命名法 这是 C++ 标准库和许多 C++ 社区(如 Boost)最推荐的风格。小写蛇形命名法:所有字母小写,单词之间用下划线 _ 连接。适用于:变量、函数、命名空间、文件。 示例…

最小二乘问题详解6:梯度下降法

介绍了使用梯度下降法求解非线性最小二乘问题的原理与实现,通过C++和Eigen库对指数模型进行参数拟合,展示了算法流程、雅可比矩阵计算及收敛行为,并对比了其在机器学习与计算机视觉中的应用差异。1. 引言 在之前的两…

JavaWeb01

1.JavaWeb介绍 什么是JavaWeb?Web:全球广域网,也称万维网(www),能够通过浏览器访问的网站 JavaWeb:使用Java技术来解决相关web互联网领域的技术栈网页:展现数据 数据库:存储和管理数据 JavaWeb程序:逻辑处理数…