Qt鼠标处理的项目,包含事件分发、处理机制

事件处理的特点

这个项目应用了Qt 的事件是 "链式传递" 的:子控件 → 父控件 → 应用程序的方法

本项目问题

在设置右键光标时是基于窗口的,但是在文本框右键一下后会一直显示光标,出现bug

解决:安装事件过滤器

一.鼠标按下和松开事件处理

1.鼠标项目需求

2.鼠标松开和按下

子类处理事件后,建议调用父类内容(可能父类有一些新的需求/行为),Qt 的事件处理是 "链式" 的,父类实现包含了控件正常工作的基础逻辑

1.保持控件原有行为

2.遵循 Qt 的事件重写规范

Qt 设计虚函数(如 mousePressEvent)的初衷是:

子类扩展父类功能,而不是替换

自定义逻辑 + 父类默认逻辑 = 完整的事件处理

二.窗口设置及其重要函数

问题 : 双击左键全屏操作

WidgetNoState:恢复以前状态

setWindowState 是 Qt 中 QWidget 类的成员函数,作用是主动设置窗口的显示状态

可以利用这个嵌套

作用举例:

利用(WindowState = 窗口状态)判断窗口状态

WindowState:单状态(只能描述主要状态)

WindowStates:复合状态(因为窗口可能同时有多个状态)

(1)窗口可以同时是「最大化 + 激活」(比如你正在用的最大化窗口)

但 windowState()(单数)只能返回 "主要状态"(比如只返回最大化,丢了激活状态)

这时就需要 windowStates()(复数)来精准判断

(2)用 &(按位与)来判断是否包含某个状态:

// 判断是否最大化(推荐新手用这个写法)

if (windowStates() & Qt::WindowMaximized) {

qDebug() << "窗口是最大化的"; }

(3)if (windowStates() & (Qt::WindowMaximized | Qt::WindowActive)) {

qDebug() << "窗口是最大化且处于激活状态"; }

光标

光标图片支持DPI方法:RCC资源

三.坐标数值处理

1.距离概述

1.1距离的函数

position()是到窗口距离

globalPosition()是到屏幕距离

先按住鼠标,再根据这两个举例计算

x=g-p,移动时不断计算距离,所以每次都保存一下相对偏移量

1.2 浮点数/整型坐标点的类

QPointF 是什么?

是 Qt 框架中用于表示二维浮点数坐标点的类

存储坐标;图形计算

QPoint:存储 int 类型坐标,适合像素级定位

1.3 event->buttons()和event->button区别

event->buttons() 是 Qt 中鼠标事件类(QMouseEvent)的核心方法,用于获取当前按下的所有鼠标按键组合

event->button():只返回最后一次触发事件的那个按键(单次按键)。

event->buttons():返回当前所有处于按下状态的按键组合(适合判断多键同时按下,比如拖拽时)

注意 : 并且必须用按位与 & 来判断某个按键是否被按下,不能直接用 == 比较

1.4思路

移动和坐标有关,先获取鼠标当前位置,然后再实现坐标变换

2. 窗口瞬移问题和修改:

当前坐标直接用pos()时,会出现数值移动卡顿直接跳转的情况

方法:

直接算pos()坐标 : 算控件距离屏幕坐标,在和globalPosition()相减,得到框架实际大小(具体如下代码所示)

本质原因:

拖拽的目标是「让鼠标按住的位置跟着鼠标动」,而不是「让控件左上角跟着鼠标动」

解释:拖拽时,无论鼠标移到哪,控件的新位置 = 鼠标当前位置 - 这个偏移量 → 保证「鼠标按住的那个点」始终和鼠标粘在一起,拖拽平滑不瞬移

也就是用鼠标当前位置表示,而不是用鼠标相对左上角原点的位置表示

3.距离函数类型的对比

pos() 核心作用:定位控件的 "左上角坐标地址"

position()(鼠标事件成员)

pos()(控件成员)和 position()(鼠标事件成员)是 Qt 坐标体系中同参考系但不同主体的两个函数,核心关系可以总结为:两者都是「控件局部坐标系」的坐标,但前者描述「控件位置」,后者描述「鼠标位置」

globalPosition():核心作用是获取鼠标光标在「整个屏幕坐标系」中的绝对位置(浮点数精度)

globalPos():整数坐标(优先级低于上面的)

四.滚轮事件

QCloseEvent写法

QWheelEvent

1. 四类核心方法

(1)QPoint angleDelta() const

含义:获取滚轮滚动的角度增量(以 1/8 度为单位)

典型值:

向上滚动:QPoint(0, 120)(120 代表 15°)

向下滚动:QPoint(0, -120)

水平滚动:x 分量不为 0(如部分鼠标 / 触摸板)

用途:传统滚轮操作的标准判断方式,适合按 "步长" 处理滚动(如每次滚动翻页)

大于0向上滚,小于0向下滚

(2)bool inverted() const

含义:判断当前滚动是否为自然滚动(反向滚动)

返回值:

true:滚动方向与系统 "自然滚动" 设置一致(如 macOS 触摸板,手指向上推,内容向上滚)

false:传统滚动方向(滚轮向上滚,内容向上滚)

用途:适配不同系统的滚动习惯,保证用户体验一致

(3)Qt::ScrollPhase phase() const

含义:获取当前滚动的阶段(主要用于触摸板 / 触摸屏的连续滚动)

枚举值:

Qt::NoScrollPhase:无阶段(普通鼠标滚轮)

Qt::ScrollBegin:滚动开始(手指刚按下)

Qt::ScrollUpdate:滚动中(手指持续移动)

Qt::ScrollEnd:滚动结束(手指抬起)

Qt::ScrollMomentum:惯性滚动阶段(手指抬起后继续滚动)

用途:实现流畅的触摸板滚动效果,区分 "主动滚动" 和 "惯性滚动"

(4)QPoint pixelDelta() const

含义:获取滚轮滚动的像素增量(高精度,以像素为单位)

典型场景:

高分辨率鼠标 / 触摸板的精细滚动

触摸板双指滑动(直接对应像素位移)

用途:适合实现平滑滚动(如图片缩放、地图拖动),比 angleDelta() 更精准

实用建议

普通滚轮场景:优先用 angleDelta(),兼容性最好

触摸板 / 高精度场景:优先用 pixelDelta(),滚动更丝滑

跨平台体验:结合 inverted() 和 phase(),适配不同系统的滚动习惯

具体放大缩小/上滚下滚看实际效果

2. 事件延申

在该输入框界面还有一个子界面(子界面不滚动缩放),当鼠标在子界面滑动滚轮时

利用知识:子类处理不了的事件(子对象忽略)同时交给他的父类处理

五.退出框

利用对话框形式构建的

核心:QMessageBox 作用

QMessageBox 是 Qt 提供的标准对话框类,用于快速弹出 "提示 / 警告 / 确认 / 错误" 类的消息框,无需手动创建窗口,一行代码就能实现和用户的简单交互,是 Qt 开发中最常用的 "弹窗工具"

函数声明

QMessageBox类

resize()设置宽和高

move()移动窗口

resize不定义move时,自定义是在原点处

核心特点:

跨平台统一样式(自动适配 Windows/macOS/Linux 系统风格)

内置多种预设类型(提示、警告、错误、提问)

支持自定义按钮、图标、文本

阻塞式弹窗(默认):弹窗关闭前,代码不会继续执行

这里运用QMessageBox::question方式

五.代码

.h

.cpp

相关推荐
用户805533698035 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner5 天前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz10 天前
QML Hello World 入门示例
qt
xcyxiner13 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner13 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner14 天前
DicomViewer (添加模型类)3
qt
xcyxiner14 天前
DicomViewer (目录调整) 2
qt
xcyxiner14 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
桥田智能16 天前
桥田智能 QT-650S:面向白车身焊装的 800kg 重载快换解决方案
开发语言·qt·系统架构
森G16 天前
75、服务器源码解析---------云视频服务项目
linux·服务器·网络·c++·qt