Qt5自定义QGraphicsView控件中两类手型光标尺寸过小问题求解
问题原因
这是Qt5在Windows平台的已知实现问题:
- 大部分
Qt::CursorShape枚举对应的光标,Qt底层会直接调用Windows系统原生的光标资源,所以会自动跟随系统的光标大小、DPI缩放配置 - 但
Qt::OpenHandCursor和Qt::ClosedHandCursor这两个枚举,Qt5没有做对应的系统原生光标映射,而是直接内置了固定16x16尺寸的位图资源来渲染,不管系统光标设置多大,都会用这个固定尺寸的位图,所以永远显示最小尺寸。
解决方法
你可以替换这两个光标为自己创建的、适配系统尺寸的自定义光标,步骤如下:
- 先获取系统当前的光标推荐尺寸,可以调用
QCursor::size()获取当前系统适配的光标最佳尺寸 - 准备对应尺寸的开放手、握拳手图标,或者调用Windows原生API加载系统自带的对应光标资源
- 替换原来直接返回枚举值的逻辑,这两个场景返回自定义的
QCursor对象即可
代码示例
修改你的光标获取逻辑,把这两个枚举的分支换成自定义光标:
#include <QCursor> #include <QPixmap> // 用Windows原生API的话需要加对应头文件 #ifdef Q_OS_WIN #include <windows.h> #endif QCursor MyClass::custom_cursor() { if(<指向手触发条件>) { return Qt::PointingHandCursor; // 该类型原生支持系统适配,直接用即可 } if(<握拳手触发条件>) { #ifdef Q_OS_WIN // 方案1:调用Windows原生API加载系统自带的对应光标 static HCURSOR hClosedHand = LoadCursor(NULL, IDC_HAND); // 如果系统自带的光标不符合要求,也可以替换为自己准备的资源ID return QCursor(hClosedHand); #else // 方案2:跨平台通用方案,用自定义图标 QSize cursorSize = QCursor::size(); QPixmap pix(":/icons/closed_hand.png"); pix = pix.scaled(cursorSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); // 后面两个参数是光标热点坐标,根据你的图标实际情况调整 return QCursor(pix, pix.width()/2, pix.height()/2); #endif } if(<开放手触发条件>) { // 同上逻辑,替换为开放手对应的光标资源即可 } // 其余原有逻辑保持不变 }
后续调用的时候直接用setCursor(custom_cursor())即可,无需修改其他调用逻辑。
注意事项
- 如果用自定义图标方案,建议准备多套不同分辨率的图标适配不同DPI和光标尺寸,避免缩放后模糊
- Qt6已经修复了内置光标适配系统尺寸的问题,如果后续升级到Qt6可以直接换回原来的枚举实现
内容的提问来源于stack exchange,提问作者Aziuth
相关产品推荐
相关产品推荐

