• 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;
    }
    
  • 相关阅读:
    这样做框架结构图,让你的PPT更有创意!
    CentOS7安装Jenkins(更改默认运行的端口号8080->16060)
    【Spring框架】Spring概述及基本应用
    java笔试题含答案总结四
    AVL树简介
    广州移动中兴B860AV3.1-M2_S905L3安卓9.0线刷包
    【Android笔记56】Android之内容观察者Content Observer介绍及其使用
    java---哈希表插入和查询---数组模拟(每日一道算法2022.8.18)
    参数化的 4 种方式用法总结
    django项目实战基于Python实现的衣物捐赠系统
  • 原文地址:https://www.cnblogs.com/ITnoteforlsy/p/18072974