QT 使用QPixmap自定义光标 缩放图像模糊问题
QT中定义光标可以使用 Qt::CursorShape 预定义 的光标,也可以使用 QBitmap 和 QPixmap 自己绘制光标。QBitmap 只有黑白2色,QPixmap可以绘制彩色光标。使用QPixmap绘制光标时会出现光标边界模糊的情况,尤其是显示器设置缩放比例时,光标更是模糊。
出现模糊的原因有2个:
- QPixmap 投射到屏幕时自动进行了缩放,出现了图像缩放失真;
- 缩放时默认采用的算法导致图像信息丢失;
解决办法:
- 获取屏幕的缩放比例。
// 获取主屏幕的缩放比例
qreal screenRatio = QGuiApplication::primaryScreen()->devicePixelRatio();
qreal width = 32;
qreal height = 32;
// 创建位图,根据屏幕缩放比例调整图形大小
QPixmap pixmap(width*screenRatio, height*screenRatio);
pixmap.fill(Qt::transparent);
pixmap.setDevicePixelRatio(screenRatio);
- 选择更平滑的图像缩放算法。
QPainter painter(&pixmap);
painter.setRenderHint(QPainter::Antialiasing);
// 出现缩放时选择更平滑的缩放算法
painter.setRenderHint(QPainter::SmoothPixmapTransform);
完整的自定义光标代码:
/**
* @brief 绘制光标
* @param width 光标宽带
* @param height 光标高度
*/
void AdjustPoint::createCursor(qreal angleOffset)
{
qreal width = 32;
qreal height = 32;
// 创建位图,根据屏幕缩放比例调整图形大小
QPixmap pixmap(width*screenRatio, height*screenRatio);
pixmap.fill(Qt::transparent);
pixmap.setDevicePixelRatio(screenRatio);
// 绘制
QPainter painter(&pixmap);
painter.setRenderHint(QPainter::Antialiasing);
painter.setRenderHint(QPainter::SmoothPixmapTransform);
painter.setRenderHint(QPainter::VerticalSubpixelPositioning);
painter.setRenderHint(QPainter::LosslessImageRendering);
qreal winWidth = 20;
qreal winHeight = 8;
painter.setViewport((width - winWidth) / 2,(height - winHeight) / 2,
winWidth,winHeight);
painter.setWindow(-winWidth / 2,-winHeight / 2,winWidth,winHeight);
// 旋转光标图像到指定位置
painter.rotate(cursorAngle + angleOffset);
QPen pen(Qt::NoPen);
painter.setPen(pen);
QBrush brush(Qt::SolidPattern);
brush.setColor(QColor(borderColor));
painter.setBrush(brush);
painter.drawPath(createArrowPath(winHeight+2, winWidth+1));
brush.setColor(QColor(cursorColor));
painter.setBrush(brush);
painter.drawPath(createArrowPath(winHeight, winWidth));
painter.end();
// 创建光标,并设置
QCursor customCursor(pixmap);
setCursor(customCursor);
}
QPainterPath AdjustPoint::createArrowPath(qreal winHeight, qreal winWidth)
{
QPainterPath path;
qreal x1 = -winWidth / 2;
qreal x2 = x1 + winHeight / 2;
qreal x3 = -x2;
qreal x4 = -x1;
qreal y1 = -winHeight / 2;
qreal y2 = -winHeight * 1 /8;
qreal y3 = -y2;
qreal y4 = -y1;
path.moveTo(x1, 0);
path.lineTo(x2,y1);
path.lineTo(x2, y2);
path.lineTo(x3, y2);
path.lineTo(x3,y1);
path.lineTo(x4, 0);
path.lineTo(x3, y4);
path.lineTo(x3, y3);
path.lineTo(x2, y3);
path.lineTo(x2, y4);
path.lineTo(x1, 0);
path.closeSubpath();
return path;
}
QT 使用QPixmap自定义光标 缩放图像模糊问题的更多相关文章
- 在.NET中实现彩色光标/动画光标和自定义光标[转]
下面是完整的例子,可以通过命令行编译即可看到效果. Test.cs using System; using System.Drawing; using System.Windows.Forms; us ...
- Qt:使用自定义的字体
Qt:使用自定义的字体 1. 下载字体文件 2. 加载字体文件 3. 使用字体 QFontDatabase::addApplicationFont("XENOTRON.TTF" ...
- CSS超链接-光标-缩放
CSS超链接-光标-缩放 1.CSS 中链接的使用2.CSS 中光标的使用3.CSS 中缩放的使用 1.CSS 中链接的使用超链接伪类属性a:link 表示该超链接文字尚未被点选a:visite ...
- 在ListCtrl控件中设置自定义光标
::SetCursor(::LoadCursor (::AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BMP_MOUSE))); void CMy ...
- C# 全屏坐标及区域坐标获取。自定义光标及系统光标描边捕捉显示。
最近手头工作比较轻松了一点就继续研究和完善之前的录屏软件,使用AForge最大的问题在于:最原始的只能够录全屏,而自定义的录屏需要更改非常多的细节:like follows: 1.需要支持区域化录屏: ...
- Qt信号之自定义数据类型
[1]为什么需要自定义数据类型? 内置类型毕竟很有局限性,否则为什么还需要类呢.总之,有时候,我们多么希望信号能发送自定义数据类型. 幸哉~ Qt是支持自定义信号,且自定义信号可以发送自定义数据类型的 ...
- Qt之创建自定义类型
摘要: 简述 当使用Qt创建用户界面时,特别是那些带有特殊控制和特征的界面时,开发者通常需要创建新数据类型来扩展或替换Qt现有的的值类型集合. 标准类型,比如:QSize.QColor和QString ...
- Android 自定义光标样式
今天自定义光标,自己切图,不过怎么切都是很宽.不是一个很细的条.我用ps花了一个像素的直线,放上去还是不行.后来在网上找到方法,那就是用shape.不得不说,shape真的是太吊了. 给EditTex ...
- Qt之如何自定义model
Qt之如何自定义model https://blog.csdn.net/wei375653972/article/details/86592209
- QT使用提升自定义组件
QT使用提升自定义组件 QTC++QT自定义 QT 组件提升来实现自定义功能 介绍 我们在使用QT设置界面之后,往往需要自己实现一些方法,如果是单独 的还好,但是如果遇到很多同类型的都有需求, 比如 ...
随机推荐
- 文心一言 VS 讯飞星火 VS chatgpt (194)-- 算法导论14.3 2题
二.用go语言,改写 INTERVAL-SEARCH 的代码,使得当所有区间都是开区间时,它也能正确地工作. 文心一言,代码正常运行: 在Go语言中,处理开区间(open intervals)时,我们 ...
- 一份55页Java性能调优PPT分享
提起"肖桦"这个人,相信很多小伙伴对他比较陌生.除去现任唯品会资深技术专家头衔外,他更为技术圈所熟知的是他的著名开源项目:SpringSide. SpringSide是以sprin ...
- 【Unity3D】半球卷屏特效
1 原理 凸镜贴图 和 渐变凸镜贴图 中介绍了使用 OpenGL 实现凸镜贴图及其原理,通过顶点坐标映射到纹理坐标,并构造三角形网格,构建了真正的三维凸镜模型.本文通过 Shader 实现半球卷屏 ...
- 优先队列(PriorityQueue)常用方法及简单案例
1 前言 PriorityQueue是一种特殊的队列,满足队列的"队尾进.队头出"条件,但是每次插入或删除元素后,都对队列进行调整,使得队列始终构成最小堆(或最大堆).具体调整如下 ...
- MySQL数据库备份与恢复方法
MySQL数据库备份与恢复方法 mysql -uroot -p show databases; 1.导出数据库 1).MySQL命令行导出整个数据库(包含数据) 导出文件默认是存在mysql\bin目 ...
- New Questions
1. C++/Qt 实现一个信号槽 #include <functional> #include <iostream> #include <vector> clas ...
- http 与 tcp 的一些学习
HTTP 是一个基于 TCP/IP 通信协议来传递数据的协议,传输的数据类型为 HTML 文件,.图片文件, 查询结果等. HTTP 协议一般用于 B/S 架构().浏览器作为 HTTP 客户端通过 ...
- Java Http客户端选型
JDK自带 HTTPURLConnect:功能单一 Apache HttpClient https://hc.apache.org/index.html 是一个比较古老的HTTP框架,使用非常普遍. ...
- FileBeat简单使用
简介 首先要了解ELK架构 这种结构因为需要在各个服务器上部署 Logstash,而它比较消耗 CPU 和内存资源,所以比较适合计算资源丰富的服务器,否则容易造成服务器性能下降,甚至可能导致无法正常工 ...
- 混合类Mixins介绍
介绍 混合类是封装了一些通用行为的基类,旨在重用代码.通常,混合类本身并没有什么用,仅扩展这种类也行不通 因为在大多数情况下,它都依赖于其它类中定义的方法和属性.通过多继承,可将混合类与其它类一起使用 ...