Qt5.14.2 全面解锁Qt5事件处理的精髓


上一篇博文中,我们从高空中俯瞰了Qt5事件编织的壮阔进程。无论是最普通的鼠标点击,还是最先进的多点触控手势,抑或是跨越线程的事件传递,Qt5都为开发者们提供了一整套完备的事件处理方案和强大工具链,只等着你来施展渔阳鼎力,尽情驰骋拳打脚踢。


现在,就让我们放眼脚下,深入研究其中最为普通而又至关重要的鼠标和键盘事件吧! 毕竟,它们就如同GUI应用程序的肢体神经,承载着人机交互的一切。那么,Qt5是如何帮助我们精准捕捉和优雅响应这些来自用户的交互指令呢?让我们拨开重重迷雾,一一揭晓!


一、鼠标键盘事件


1、指尖下的强力舵手 - 鼠标事件的操纵杆

鼠标可以说是GUI程序中最常见和最主要的交互方式了。Qt5提供了多个类来帮助我们精准无误地处理各种鼠标事件,如QMouseEvent、QHoverEvent、QTabletEvent等。而QWidget及其派生类中的鼠标事件处理函数,就是驾驶这一切的高级操纵杆:

void MyWidget::mousePressEvent(QMouseEvent *event)
{if (event->button() == Qt::LeftButton) {// 处理鼠标左键按下...}
}void MyWidget::mouseMoveEvent(QMouseEvent *event)
{// 处理鼠标移动...
}void MyWidget::mouseReleaseEvent(QMouseEvent *event) 
{if (event->button() == Qt::RightButton) {// 处理鼠标右键释放...}
}

无论用户何时点击鼠标按钮、移动鼠标或停留在窗口区域,这些事件首先会分别进入对应的事件处理函数。我们只需要重新实现这些函数,根据QMouseEvent提供的坐标、按钮、修饰键等信息,编写自己的业务逻辑,就可以完全掌控鼠标交互了。


别忘了mousePressEvent和mouseReleaseEvent还有一个双击形式的兄弟 - mouseDblClickEvent,用于处理鼠标双击。另外,QHoverEvent也是判断鼠标悬停的重要线索。


2、神剑勾魂 指尖乾坤 - 键盘敲击的分秒必争


键盘输入是另一种重要的GUI交互方式,尤其在输入文本信息或快捷键操作时。而Qt5通过QKeyEvent和QShortcutEvent等类,也为开发者提供了驾驭键盘指令的利器:

void MyWidget::keyPressEvent(QKeyEvent *event)
{if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) {// 处理回车键被按下...} else if (event->matches(QKeySequence::Copy)) {// 处理复制快捷键被按下...}
}void MyWidget::keyReleaseEvent(QKeyEvent *event)
{// 处理按键释放...
}void MyWidget::customShortcut()
{QShortcut *shortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_X), this);connect(shortcut, &QShortcut::activated, this, &MyWidget::handleCustomShortcut);
}

通过重写keyPressEvent和keyReleaseEvent方法,我们就能拦截并响应用户的每一次按键动作。QKeyEvent提供了被按下的按键信息,我们可以方便地进行判断和处理。

而对于常用的快捷键组合,如复制粘贴等,Qt5还为我们提供了QKeySequence的高级工具,使用它可以非常方便地检查按键是否匹配快捷键。

当然,有时候我们也需要自定义快捷键,这时就可以利用QShortcut来创建全局或上下文快捷键。只需将想要的键序列和处理函数连接起来,就可以完成快捷键操作了。


3、挥剑斩浪 壹气呵成 - 鼠标键盘并重的艺术馆


在现代的GUI应用中,鼠标和键盘输入往往是并重出击的。比如在文本编辑器中,我们可能先是使用鼠标进行区域选择,再通过键盘输入命令执行操作。再比如在绘图软件里,我们需要结合鼠标与键盘输入,来完成多种交互动作。

但是鼠标和键盘事件最终都需要在同一个事件处理中完成,这就要求我们设计出更加复杂的交互逻辑。幸运的是,Qt5为我们提供了多个辅助工具和技术:

// 使用按键修饰键
if (event->modifiers() & Qt::ShiftModifier) {// Shift键被按下时执行的逻辑
}// 鼠标光标设置
if (someCondition) {setCursor(Qt::PointingHandCursor);
} else {setCursor(Qt::ArrowCursor);
}// 焦点策略
setFocusPolicy(Qt::ClickFocus); // 单击时自动获取键盘焦点

首先是修饰键,像Shift、Ctrl、Alt等常用键被按下时,会体现在鼠标或键盘事件的modifiers()中。利用这一点,我们就能轻松地对组合键做出响应。

其次,Qt还提供了丰富的鼠标光标形状,可以根据不同状态和场景,方便地切换鼠标光标的样式,为用户提供更多视觉线索。

最后,焦点策略也是整合鼠标和键盘事件的重要一环。我们可以控制键盘焦点在窗口间的移动规则,使之与鼠标交互相呼应,为用户提供一致的体验。


二、触控手势


1、天地鼓动 掌跆指挥 - 触控手势交互的新时代

随着智能手机、平板电脑的普及,触控和手势这种全新的交互方式越来越受到重视。传统的鼠标和键盘在移动设备上已经无法满足用户需求,因此Qt5也及时跟上了这股潮流,为开发者提供了处理触控和手势事件的完备支持。

bool MyWidget::event(QEvent *event)
{if (event->type() == QEvent::Gesture) {// 处理手势事件QGestureEvent *gestureEvent = static_cast<QGestureEvent *>(event);qDebug() << "Gesture event detected with" << gestureEvent->gestures().size() << "gestures";for (QGesture *gesture : gestureEvent->gestures()) {if (QPinchGesture *pinch = qobject_cast<QPinchGesture *>(gesture)) {// 捕捉到pinch手势qreal scaleFactor = pinch->totalScaleFactor();if (pinch->state() == Qt::GestureStarted) {lastScaleFactor = scaleFactor;} else if (pinch->state() == Qt::GestureUpdated) {// 更新缩放比例updateScaleFactor(scaleFactor / lastScaleFactor);lastScaleFactor = scaleFactor;}}}return true;} else if (event->type() == QEvent::TouchBegin) {// 处理触摸按下事件...}return QWidget::event(event);
}

这段代码展示了如何在event()函数中捕获手势事件和触摸事件。QGestureEvent包含了一个或多个QGesture对象,用于描述发生的手势类型,如QPinchGesture代表了两指缩放手势。

开发者可以遍历QGestureEvent中的所有手势对象,识别出自己感兴趣的手势类型,并根据手势的状态和属性值编写响应逻辑。

除了手势事件,还有专门的QTouchEvent类用于获取原始的多点触摸信息,如按下、移动、释放等。结合这两种事件类型,就能实现丰富的触控手势交互体验了。


三、云穷野极 水到渠成 - 纵横多线程也能游刃有余


在现代计算机系统中,单线程的计算能力已经无法满足日益复杂的需求。而Qt5本身就是一个多线程友好的框架,它对线程间事件的传递有着深度的支持和优化。

// 工作线程
QThread workerThread;
QObject *myObject = new MyObject;
myObject->moveToThread(&workerThread);
workerThread.start();// 发送自定义事件到工作线程
QMetaObject::invokeMethod(myObject, "handleEvent", Q_ARG(QString, "Hello from main thread!"));class MyObject : public QObject
{Q_OBJECT
public slots:void handleEvent(const QString &message){qDebug() << "Received event from main thread:" << message;}
};// GUI线程 
void setupGUI()
{QLabel *label = new QLabel;label->show();// 从工作线程更新UIQMetaObject::invokeMethod(label, "setText", Q_ARG(QString, "New text"), Qt::QueuedConnection);
}

这个示例展示了如何在Qt应用中横跨多线程。首先我们创建了一个工作线程,并让MyObject对象在该线程中运行。然后通过QMetaObject::invokeMethod方法,我们就能安全地将事件对象或信号发送到目标线程中。


值得注意的是,invokeMethod有多种连接类型可选,Qt::QueuedConnection可以将目标方法调用安全地加入事件队列,确保跨线程调用的安全性。

在上例中,我们还展示了如何利用invokeMethod从非GUI线程更新UI。只需以Qt::QueuedConnection的方式调用UI组件的方法,就能避免跨线程问题。

通过Qt提供的这些工具,我们就能轻松驾驭多线程开发中的种种复杂情况,毫无后顾之忧。当然,多线程开发本身就是一个贯穿始终的重要主题,我们后续还会专门就此进行更深入的探讨。


四、海阔凭鱼跃 天高任鸟飞 - 你终将驾驭住这对强将


通过本篇博文,我们系统地学习了Qt5下如何高效地处理鼠标和键盘事件。从最基本的事件处理函数入手,到组合键、光标和焦点策略的高级特性,Qt5都为开发者们提供了一整套强大而易用的武器库。


我们今天的旅程仅仅揭开了事件处理的一角。但放眼Qt的广阔天地,却有太多更高境界等着我们去开拓和征服。勇敢前行吧,未来属于勇猛者! 下一期博文,我将为您开启全新的征程,让我们共同攀登事件编程的巅峰!


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

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

相关文章

【面试题】ES文档写入和读取流程详解

前言&#xff1a;在回答这个问题之前我们先要搞清楚一个问题那就是什么是文档&#xff0c;避免不知所云&#xff01; 一、什么是文档&#xff1f; 在Elasticsearch中&#xff0c;文档&#xff08;Document&#xff09;是最基本的信息单元&#xff0c;用于表示和存储数据。文…

Android 系统应用 pk8签名文件转jks或keystore教程

一、介绍 签名文件对于我们在做应用开发中&#xff0c;经常遇到&#xff0c;且签名文件不仅仅是保护应用安全&#xff0c;还会涉及到应用与底层之间的数据共享和API文件等问题。 在Android中&#xff0c;签名文件同样也存在这个问题。但是android中又区分系统应用和普通应用。系…

C语言 青蛙跳台阶问题

目录 ​编辑 1.问题描述 2.问题分析 3.全部代码 4.结语 1.问题描述 一只青蛙可以一次跳一级台阶&#xff0c;也可以一次跳两级台阶&#xff0c;如果青蛙要跳上n级台阶有多少种跳法&#xff1f; 2.问题分析 当台阶只有一级时&#xff0c;只能跳一级&#xff0c;所以只有一…

用 C++ 编码架构图的最佳用例

统一建模语言&#xff08;UML&#xff09;&#xff0c;作为一种实际应用的语言标准&#xff0c;借助一系列架构图呈现建模软件系统。UML 的出现鼓励了自动化软件工具的开发&#xff0c;有助于自动代码生成。UML 图面向对象系统和软件工具&#xff0c;将静态结构和动态行为以可视…

注册、配置中心-微服务小白入门(2)

Nacos 已经下载安装并且使用了&#xff0c;那么看如何使用&#xff1a; Nacos 注册及配置&#xff0c;以下是一个服务启动后注册到nacos&#xff0c;同时&#xff0c;把该服务的相关配置&#xff0c;写到nacos之中 1、nacos设置 命名空间中&#xff0c;添加对应的服务命名空间…

Jenkins中支持maven构建遇到仓库报错问题

目的 Jenkins中支持maven构建(Jenkins使用docker安装&#xff09; 问题 1.构建一个maven项目 2.执行报错 /var/lib/jenkins/local_maven_repo/com/sx/root/1.0.4/root-1.0.4.pom.part.lock (No such file or directory) Failed to transfer Could not transfer artifact co…

【Flask】Flask项目部署上线

Flask 项目部署上线 1.Gunicorn Gunicorn 是一个纯 Python WSGI 服务器&#xff0c;配置简单&#xff0c;多工作者实现&#xff0c;方便 性能调优。 它倾向于与主机平台轻松集成。 它不支持 Windows &#xff08;但可以在 WSL 上运行&#xff09;。 它很容易安装&#xff0…

论文阅读之PeriodicLoRA: Breaking the Low-Rank Bottleneck in LoRA Optimization(2024)

文章目录 论文地址主要内容主要贡献模型图技术细节实验结果 论文地址 PeriodicLoRA: Breaking the Low-Rank Bottleneck in LoRA Optimization 主要内容 这篇文章的主要内容是介绍了一种名为PeriodicLoRA&#xff08;PLoRA&#xff09;的参数高效微调&#xff08;Parameter-…

TypeScript在学习(0)

1.什么是TypeScript? 答:TypeScript 是一种由微软开发的自由和开源的编程语言。它是 JavaScript 的一个超集&#xff0c;而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程。 个人浅见&#xff0c;我一直把ts简单理解成&#xff0c;其实就是javascript上多了…

SAP Fiori开发中的JavaScript基础知识3 - 类型转换,逻辑true和false

1 背景 在上一篇博客中&#xff0c;我我介绍了JavaScript最基本的语法&#xff0c;包括变量&#xff0c;操作符&#xff0c;值&#xff0c;类型的概念。在本篇博客中&#xff0c;我将介绍JavaScript中的类型转换逻辑&#xff0c;以及逻辑真假的概念。这些都属于JavaScript中最…

DY-36电压继电器 额定电压100V 整定范围40-160V 板前带座 JOSEF约瑟

系列型号&#xff1a; DY-32电压继电器&#xff1b; DY-36电压继电器&#xff1b; DY-33电压继电器&#xff1b; DY-37电压继电器&#xff1b; DY-34电压继电器&#xff1b; DY-38电压继电器&#xff1b; DY-31电压继电器&#xff1b; DY-35电压继电器&#xff1b; DY-32/60C电…

YOLO算法改进Backbone系列之:Conformer

CNN难以捕捉全局表征&#xff0c;这通常对高级计算机视觉任务至关重要。一个直观的解决方案是扩大感受野&#xff0c;但这可能需要更密集但具有破坏性的池化操作。由于自注意力机制和多层感知器&#xff08;MLP&#xff09;结构&#xff0c;transformer反映了复杂的空间变换和长…

Vue3 + vite + Ts 组件间通信

Vue3 vite Ts 组件间通信 1、props2、自定义事件3、mitt4、$attrs 1、props 概述&#xff1a;props 是使用频率最高的一种通信方式&#xff0c;常用与&#xff1a;父 和 子 互相传递 若 父传子 &#xff1a;属性值是非函数。若 子传父 &#xff1a;属性值是函数。 简单例子&…

【C++】this关键字和new关键字

一、this关键字 在 C 中&#xff0c; this 关键字是一个 指向调用对象的指针 。它在成员函数内部使用&#xff0c;用于引用调用该函数的对象。使用 this 可以明确指出成员函数正在操作的是哪个对象的数据成员。 示例&#xff1a; #include <iostream>using namespa…

网红电商主播培养体系招聘管理制度孵化方案

【干货资料持续更新&#xff0c;以防走丢】 网红电商主播培养体系招聘管理制度孵化方案 部分资料预览 资料部分是网络整理&#xff0c;仅供学习参考。 共120页可编辑&#xff08;完整资料包含以下内容&#xff09; 目录 主播团队组建方案 让好主播主动留下 1. 好主播选拔标准…

【Flink】Flink 处理函数之基本处理函数(一)

1. 处理函数介绍 流处理API&#xff0c;无论是基本的转换、聚合、还是复杂的窗口操作&#xff0c;都是基于DataStream进行转换的&#xff0c;所以统称为DataStreamAPI&#xff0c;这是Flink编程的核心。 但其实Flink为了更强大的表现力和易用性&#xff0c;Flink本身提供了多…

学习SpringBoot笔记--知识点(2)

目录 数据访问 基础特性 自定义banner Profiles Profiles组件 Profiles配置文件 外部化配置 单元测试 数据访问 整合SSM场景 SpringBoot 整合 Spring&#xff0c;SpringMVC&#xff0c;MyBatis 进行数据访问场景开发 需要的依赖&#xff1a; <!-- web启动…

leetcode 518.零钱兑换 II

思路&#xff1a;和第一道是一样的问题&#xff0c;也就是完全背包问题。 我们首先可以看到&#xff0c;每一个数都是可以重复使用的&#xff0c;而且&#xff0c;数的选择上有两种&#xff0c;一种就是选&#xff0c;一种就是不选。所以会想到完全背包问题。 上一个题的零钱…

如何从其他平台复制商品上传到自己店铺?官方授权接口,一键复制爆款同款

很多做一件代发的卖家在上新时会从其他平台选品铺货&#xff0c;看到某个商品卖得不错&#xff0c;直接复制到自己店铺去卖&#xff0c;可以节省测款成本。 现在平台严查无货源&#xff0c;直接从别人店铺搬运商品属于违规违规行为&#xff0c;想要复制这个爆款的话&#xff0…

鸿蒙HarmonyOS应用开发—AbilityStage组件容器

AbilityStage是一个Module级别的组件容器&#xff0c;应用的HAP在首次加载时会创建一个AbilityStage实例&#xff0c;可以对该Module进行初始化等操作。 AbilityStage与Module一一对应&#xff0c;即一个Module拥有一个AbilityStage。 DevEco Studio默认工程中未自动生成Abil…