• QT 使用QPixmap自定义光标 缩放图像模糊问题


    QT中定义光标可以使用 Qt::CursorShape 预定义 的光标,也可以使用 QBitmap 和 QPixmap 自己绘制光标。QBitmap 只有黑白2色,QPixmap可以绘制彩色光标。使用QPixmap绘制光标时会出现光标边界模糊的情况,尤其是显示器设置缩放比例时,光标更是模糊。

    显示器缩放配置

    出现模糊的原因有2个:

    1. QPixmap 投射到屏幕时自动进行了缩放,出现了图像缩放失真;
    2. 缩放时默认采用的算法导致图像信息丢失;

    解决办法:

    1. 获取屏幕的缩放比例。
        // 获取主屏幕的缩放比例
        qreal screenRatio = QGuiApplication::primaryScreen()->devicePixelRatio();
        qreal width = 32;
        qreal height = 32;
        // 创建位图,根据屏幕缩放比例调整图形大小
        QPixmap pixmap(width*screenRatio, height*screenRatio);
        pixmap.fill(Qt::transparent);
        pixmap.setDevicePixelRatio(screenRatio);
    
    1. 选择更平滑的图像缩放算法。
        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;
    }
    
  • 相关阅读:
    C语言第三章第5节数据的输出学习导案
    Starrocks 2.5.12配置项
    [2023.09.27]: Yew SSR开发中的服务器端与客户端共同维护同一状态的实践
    灵活学习平台满足不同学习风格的需求
    功率放大器如何进行阻抗匹配测试工作原理
    tensorflow学习率指数衰减ExponentialDecay的参数介绍与使用方法
    vue 滚动缩放反转图片功能
    IDEA:commit 提交插件
    rtp流广播吸顶喇叭网络有源吸顶喇叭
    软考69-上午题-【面向对象技术2-UML】-关系
  • 原文地址:https://www.cnblogs.com/ITnoteforlsy/p/18072974