【QT开发笔记-基础篇】| 第四章 事件QEvent | 4.5 键盘事件

news2024/9/29 7:24:56

本章要实现的整体效果如下:

整体效果


QEvent::KeyPress

​ 键盘按下时,触发该事件,它对应的子类是 QKeyEvent

QEvent::KeyRelease

​ 键盘抬起时,触发该事件,它对应的子类是 QKeyEvent


本节通过两个案例来讲解这 2 个事件:

  • 键盘按下、释放事件的基本使用
  • 通过键盘的上下左右箭头,控制标签控件的上下

1. 键盘按下、释放事件的基本使用

只需重写 keyPressEvent()keyPressEvent() 两个函数即可

首先,在 key_widget.h 中添加两个函数的声明

class KeyWidget : public QWidget
{
protected:
    void keyPressEvent(QKeyEvent* event);
    void keyReleaseEvent(QKeyEvent* event);
};

然后,来到 key_widget.cpp 实现这 2 个函数:

void KeyWidget::keyPressEvent(QKeyEvent* event)
{
    // 普通键
    switch ( event->key() ) {
        case Qt::Key_Return:
            qDebug() << "Enter";
            break;
        case Qt::Key_Escape:
            qDebug() << "Esc";
            break;
        case Qt::Key_Control:
            qDebug() << "Ctrl";
            break;
        case Qt::Key_Shift:
            qDebug() << "Shift";
            break;
        case Qt::Key_Alt:
            qDebug() << "Alt";
            break;
        case Qt::Key_Up:
            qDebug() << "Up";
            break;
        case Qt::Key_Down:
            qDebug() << "Down";
            break;
        case Qt::Key_Left:
            qDebug() << "Left";
            break;
        case Qt::Key_Right:
            qDebug() << "Right";
            break;
        case Qt::Key_A:
            qDebug() << "A";
            break;
        case Qt::Key_B:
            qDebug() << "B";
            break;
        case Qt::Key_C:
            qDebug() << "C";
            break;
        case Qt::Key_D:
            qDebug() << "D";
            break;
        default:
            break;
    }

    // 两键组合
    //    qDebug() << event->modifiers(); // QFlags<Qt::KeyboardModifier>(ShiftModifier|ControlModifier)
    // event->modifiers(),用来判读是否按下 Ctrl/Shift/Alt 键
    if ( (event->modifiers() == Qt::ControlModifier) && (event->key() == Qt::Key_A) ) {
        qDebug() << "Ctrl + A";
    }

    if ( (event->modifiers() == Qt::ShiftModifier) && (event->key() == Qt::Key_C) ) {
        qDebug() << "Shift + B";
    }

    if ( (event->modifiers() == Qt::AltModifier) && (event->key() == Qt::Key_B) ) {
        qDebug() << "ALT + C";
    }

    // 三键组合Shift + Ctrl + D 的实现
    if ( (event->modifiers() == (Qt::ShiftModifier | Qt::ControlModifier)) && (event->key() == Qt::Key_D) ) {
        qDebug() << "CTRL + Shift + D";
    }
}

void KeyWidget::keyReleaseEvent(QKeyEvent* event)
{
    switch ( event->key() ) {
        case Qt::Key_Return:
            qDebug() << "keyReleaseEvent: Enter";
            break;
        case Qt::Key_Escape:
            qDebug() << "keyReleaseEvent: Esc";
            break;
        case Qt::Key_Up:
            qDebug() << "keyReleaseEvent: Up";
            break;
        case Qt::Key_Down:
            qDebug() << "keyReleaseEvent: Down";
            break;
        case Qt::Key_Left:
            qDebug() << "keyReleaseEvent: Left";
            break;
        case Qt::Key_Right:
            qDebug() << "keyReleaseEvent: Right";
            break;
        case Qt::Key_A:
            qDebug() << "keyReleaseEvent: A";
            break;
        case Qt::Key_B:
            qDebug() << "keyReleaseEvent: B";
            break;
        case Qt::Key_C:
            qDebug() << "keyReleaseEvent: C";
            break;
        case Qt::Key_D:
            qDebug() << "keyReleaseEvent: D";
            break;
        case Qt::Key_Control:
            qDebug() << "keyReleaseEvent: Ctrl";
            break;
        case Qt::Key_Shift:
            qDebug() << "keyReleaseEvent: Shift";
            break;
        case Qt::Key_Alt:
            qDebug() << "keyReleaseEvent: Alt";
            break;
    }
}

说明:

  • 每个按键对应一个枚举值,比如 Qt::Key_A 代表按键 AQt::Key_Control 代表 Crtl 键,等等
  • QKeyEvent 类的 key() 方法,可以获取当前按下的哪个按键
  • 判断 Ctrl/Shift/Alt 等控制按键,需要使用 QKeyEvent 类的 modifiers() 方法

最后,还需要在构造中添加如下语句:

KeyWidget::KeyWidget(QWidget* parent) : QWidget{parent}
{
    setFocusPolicy(Qt::StrongFocus);
}

此时,运行程序,可以看到打印如下:

运行效果


2. 键盘事件移动标签

接下来,实现一个小案例:通过上下左右按键,来移动标签的位置

(1)界面上添加标签

首先,在 key_widget.h 中添加成员变量:

#include <QLabel>

class KeyWidget : public QWidget
{
private:
    QLabel* lbl;
};

然后,在 key_widget.cpp 的构造中添加一个标签:

KeyWidget::KeyWidget(QWidget* parent) : QWidget{parent}
{
    setFocusPolicy(Qt::StrongFocus);

    // 添加一个 QLabel
    lbl = new QLabel(this);
    lbl->setText("");
    lbl->setFrameShape(QFrame::Box);
    lbl->setFixedSize(100, 100);
    lbl->setStyleSheet("background-color: red;");
}

此时,运行效果如下:

运行效果


(2)移动标签

只需修改上下左右按键的逻辑即可(当移动到尽头,则从另一端重新出现开始移动):

void KeyWidget::keyPressEvent(QKeyEvent* event)
{
    // 普通键
    switch ( event->key() ) {
        case Qt::Key_Up:
            qDebug() << "Up";
            lbl->move(lbl->x(), lbl->y() - 20);
            if ( lbl->y() + lbl->height() <= 0 ) {
                lbl->move(lbl->x(), this->height());
            }
            break;
        case Qt::Key_Down:
            qDebug() << "Down";
            lbl->move(lbl->x(), lbl->y() + 20);
            if ( lbl->y() >= this->height() ) {
                lbl->move(lbl->x(), 0);
            }
            break;
        case Qt::Key_Left:
            qDebug() << "Left";
            lbl->move(lbl->x() - 20, lbl->y());
            if ( lbl->x() + lbl->width() <= 0 ) {
                lbl->move(this->width(), lbl->y());
            }
            break;
        case Qt::Key_Right:
            qDebug() << "Right";
            lbl->move(lbl->x() + 20, lbl->y());
            if ( lbl->x() >= this->width() ) {
                lbl->move(0, lbl->y());
            }
            break;
    }
}

此时,按键盘上的上下左右箭头,效果如下:

运行效果

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

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

相关文章

C++学习day4

作业&#xff1a; 1> 思维导图 2> 整理代码 1. 拷贝赋值函数课上代码 //拷贝赋值函数课上代码 #include<iostream> using namespace std;//创建类 class Stu { private://私有的string name;int socer;int *age;//此处注意用到指针类型 public://共有的//无参构…

爬取微博热榜并将其存储为csv文件

&#x1f64c;秋名山码民的主页 &#x1f602;oi退役选手&#xff0c;Java、大数据、单片机、IoT均有所涉猎&#xff0c;热爱技术&#xff0c;技术无罪 &#x1f389;欢迎关注&#x1f50e;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; 获取源码&#xff0c;添加WX 目录 前言1.…

每日leetcode_193二叉搜索树的最近公共祖先

每日leetcode_193二叉搜索树的最近公共祖先 记录自己的成长&#xff0c;加油。 题目出处&#xff1a;LCR 193. 二叉搜索树的最近公共祖先 - 力扣&#xff08;LeetCode&#xff09; 题目 思路&#xff1a; 解题 class Solution {public TreeNode lowestCommonAncestor(TreeNod…

孙帅Spring源码

【视频来源于&#xff1a;B站up主孙帅suns Spring源码视频】【微信号&#xff1a;suns45】

【二维前缀和】

目录 一、题目解析二、算法原理三、代码实现 一、题目解析 二、算法原理 三、代码实现 #include <iostream> using namespace std; #include<vector> int main() {int n0,m0,q0;cin>>n>>m>>q;vector<vector<int>> arr(n1,vector&l…

Easysearch Chart 0.2.0都有哪些变化

Easysearch Chart 包更新了&#xff0c;让我们来看看都有哪些变化&#xff1a; Docker 镜像升级 Service 名称调整&#xff0c;支持 NodePort 模式部署 现在让我们用 NodePort 模式部署一下&#xff1a; # helm search repo infinilabs NAME CHART VERSION …

移动应用-Android-开发指南

Android-UI开发指南 Android Studio调试UI设计UI框架布局Layout文本框 android的活动Activity基本概念Activity的生命周期Activity栈创建Activity管理ActivityActivity间传递数据 FragmentAdapterRecyclerViewRecyclerView Adapter&#xff08;适配器&#xff09;事件setOnItem…

C++ 与基本数据类型:整型、布尔型与字符型

文章目录 参考描述数据类型基本数据类型与复合数据类型静态数据类型 整形数据类型有符号整型数据类型无符号整型数据类型符号位 最少内存空间概念确定大小sizeof 运算符 进制C 中的不同进制数值表示cout 与进制转化影响范围二进制 后缀字面量整型字面量的默认数据类型主动权整型…

【UE5 Cesium】17-Cesium for Unreal 建立飞行跟踪器(2)

目录 效果 步骤 一、飞机沿航线飞行 二、通过切换相机实现在不同角度观察飞机飞行 效果 步骤 一、飞机沿航线飞行 先去模型网站下载一个波音737飞机模型 然后将下载好的模型导入到UE项目中&#xff0c;导入时需要勾选“合并网格体”&#xff08;导入前最好在建模软件中将…

阿里云上了新闻联播

我是卢松松&#xff0c;点点上面的头像&#xff0c;欢迎关注我哦&#xff01; 阿里新任的CEO吴泳铭上央视新闻联播了! 在昨天的新闻联播里&#xff0c;出席科技座谈会&#xff0c;有一个特别镜头&#xff0c;出现了阿里新任CEO吴泳铭的镜头。 这个信号意义明显&#xff0c;我…

sentinel的启动与运行

首先我们github下载sentinel Releases alibaba/Sentinel (github.com) 下载好了后输入命令让它运行即可&#xff0c;使用cmd窗口输入一下命令即可 java -Dserver.port8089 -jar sentinel-dashboard-1.8.6.jar 账号密码默认都是sentinel

20哈希表-三数之和

目录 LeetCode之路——15. 三数之和 分析&#xff1a; 官方题解&#xff1a; LeetCode之路——15. 三数之和 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nu…

黄金票据和白银票据

文章目录 Kerberos使用背景kerberos认证流程黄金票据和白银票据 Kerberos使用背景 1、个人文件还是公司文件以及服务都存在于一台系统上&#xff0c;所有人都要去一台机器办公&#xff0c;效率非常低&#xff0c;为每个人分配了电脑以后就需要考虑安全问题 2、如何让服务器正确…

一款好用的leetcode周赛插件:再也不用写代码的时候来回看描述了

今天发现了一个群友分享的一款leetcode插件&#xff0c;分享给大家。 对于熟悉leetcode的小伙伴应该会有一个困扰&#xff0c;那就是在leetcode打周赛的时候&#xff0c;题目描述和编辑区不是左右排版的&#xff0c;而是上下排版的&#xff0c;我们代码写着写着就需要移到最上…

设计模式 - 行为型考点模式:责任链模式(概述 | 案例实现 | 优缺点 | 使用场景)

目录 一、行为型模式 1.1、责任链模式 1.1.1、概述 1.1.2、案例实现 1.1.3、优缺点 1.1.4、使用场景 一、行为型模式 1.1、责任链模式 1.1.1、概述 为了避免请求发送者和多个请求处理者耦合在一起&#xff0c;就将所有请求处理者通过前一个对象记住下一个对象的引用的方…

飞行文本动画效果

效果展示 JavaScript 知识点 textContent.replace 方法运用anime.min.js 插件运用 实现整体页面布局 <section><p class"text">Lorem ipsum dolor sit amet consectetur, adipisicing elit. Impedit suscipitiure explicabo delectus laborum archite…

AVS3:DMVR

AVS3中引入了解码端运动矢量修正&#xff08;DMVR,Decoder side Motion Vector Refinement&#xff09;技术&#xff0c;AVS3中的DMVR技术和G.266/VVC类似&#xff0c;它可以在解码端生成运动参数从而减少传输运动参数的码率开销。它的基本思想是将skip/direct模式生成的前后向…

ArcGIS/GeoScene脚本:基于粒子群优化的支持向量机回归模型

参数输入 1.样本数据必须包含需要回归的字段 2.回归字段是数值类型 3.影响因子是栅格数据&#xff0c;可添加多个 4.随机种子可以确保每次运行的训练集和测试集一致 5.训练集占比为0-1之间的小数 6.迭代次数&#xff1a;迭代次数越高精度越高&#xff0c;但是运行时间越长…

MODBUS-RTU通信协议功能码+数据帧解读(博途PLC梯形图代码)

MODBUS通信详细代码编写,请查看下面相关链接,这篇博客主要和大家介绍MODBUS协议的一些常用功能码和具体数据帧解析,以便大家更好的理解MODBUS通信和解决现场实际问题。 S7-1200PLC MODBUS-RTU通信 博途PLC 1200/1500PLC MODBUS-RTU通讯_博图modbus rtu通讯实例-CSDN博客1、…

博弈论——动态博弈

动态博弈 0 引言 前面一篇文章介绍了博弈过程中的三个分类&#xff1a;静态博弈、动态博弈、重复博弈。今天具体讲讲动态博弈的处理方法。 博弈论——博弈过程 1 概念 首先还是介绍一下动态博弈的概念&#xff0c;即博弈中各博弈方的选择和行动不仅有先后次序&#xff0c;而…