• 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;
    }
    
  • 相关阅读:
    11、【Qlib】【主要组件】元控制器:元任务、元数据集和元模型
    java常用集合之Map
    MCE | HPV 疫苗要不要打?
    F1值(F-Measure)、准确率(Precision)、召回率(Recall) 菜鸡版理解
    StackGres 数据库平台工程,使用 Citus + Patroni 创建生产级高可用分布式 PostgreSQL 分片集群
    Nmap使用教程图文教程(超详细)
    SSM相关面试题(day3)
    ES6中的箭头函数详细梳理
    springboot+vue+nodejs+java卤菜品销售商城系统
    第七章、模板与泛型编程
  • 原文地址:https://www.cnblogs.com/ITnoteforlsy/p/18072974