QT 范例阅读:Vector Deformation

效果图:

主要代码:

复制代码
实现放大镜效果
    QPainter painter;
    //两种方式
    if (1) {
        m_lens_image = QImage(bounds.size(), QImage::Format_ARGB32_Premultiplied);
        m_lens_image.fill(0);
        painter.begin(&m_lens_image);
    } else {
        m_lens_pixmap = QPixmap(bounds.size());
        m_lens_pixmap.fill(Qt::transparent);
        painter.begin(&m_lens_pixmap); //将pixmap 当做绘图设备
    }
    
    //使用渐变的方式画圆 
    QRadialGradient gr(rad, rad, rad, 3 * rad / 5, 3 * rad / 5);
    gr.setColorAt(0.0, QColor(255, 255, 255, 191));
    gr.setColorAt(0.2, QColor(255, 255, 240, 191));
    gr.setColorAt(0.9, QColor(150, 150, 200, 63));
    gr.setColorAt(0.95, QColor(0, 0, 0, 127));
    gr.setColorAt(1, QColor(0, 0, 0, 0));
    painter.setRenderHint(QPainter::HighQualityAntialiasing);
    painter.setBrush(gr);
    painter.setPen(Qt::NoPen);
    painter.drawEllipse(0, 0, bounds.width(), bounds.height());

    //初始化文字路径

    QFontMetrics fm(f);

    m_paths.clear();  //路径 QVector<QPainterPath>
    m_pathBounds = QRect(); //整串文字大小边框

    QPointF advance(0, 0); //文字起始点

    bool do_quick = true;
    for (int i=0; i<text.size(); ++i) {
        if (text.at(i).unicode() >= 0x4ff && text.at(i).unicode() <= 0x1e00) {
            do_quick = false;
            break;
        }
    }

    if (do_quick) {
        for (int i=0; i<text.size(); ++i) {
            QPainterPath path;
            path.addText(advance, f, text.mid(i, 1)); //添加文字路径
            m_pathBounds |= path.boundingRect();
            m_paths << path;
            advance += QPointF(fm.horizontalAdvance(text.mid(i, 1)), 0);
        }
    } else {
        QPainterPath path;
        path.addText(advance, f, text);
        m_pathBounds |= path.boundingRect();
        m_paths << path;
    }

//放大镜内的文字变形
QPainterPath MainWindow::lensDeform(const QPainterPath &source, const QPointF &offset)
{
    QPainterPath path;
    path.addPath(source);  //传进来的就是m_paths[i]

    qreal flip = 100 / qreal(100);

    for (int i=0; i<path.elementCount(); ++i) {  
        const QPainterPath::Element &e = path.elementAt(i);  

        qreal x = e.x + offset.x();
        qreal y = e.y + offset.y();

        qreal dx = x - m_pos.x();
        qreal dy = y - m_pos.y();
        qreal len = m_radius - qSqrt(dx * dx + dy * dy);

        //判断在不在圆内,在则修改路径各个点的位置
        if (len > 0) {
            path.setElementPositionAt(i,
                                      x + flip * dx * len / m_radius,
                                      y + flip * dy * len / m_radius);
        } else {
            path.setElementPositionAt(i, x, y);
        }

    }

    return path;
}

绘图更新:

可以只更新 特定区域 ;如 update(rectBefore | rectAfter); //参数是两个矩形

paintEvent(QPaintEvent *e) 中 可以使用 e->rect(); 获取到要刷新的区域

相关推荐
尘中远7 分钟前
【Qwt 7.0 系列】坐标轴与刻度系统 —— 刻度引擎、网格、图例与刻度朝内
qt·数据可视化·qcustomplot·qwt·工业软件·科学绘图
sycmancia2 小时前
Qt——多线程间的互斥
开发语言·qt
尘中远7 小时前
【Qwt 7.0 系列】常用图表类型实战 —— 柱状图、散点图、箱线图与直方图
qt·qwt·工业软件·科学绘图
尘中远8 小时前
【Qwt 7.0 系列】交互功能详解 —— 平移、缩放、坐标轴交互与数据拾取
qt·数据可视化·绘图·qcustomplot·qwt·科学绘图
sycmancia8 小时前
Qt——进程与线程的概念
qt
郝学胜-神的一滴9 小时前
Qt 高级编程 034:深耕QWidget底层内核—彻底吃透无边框窗口设计核心原理
开发语言·c++·qt·程序人生·软件开发·用户界面
尘中远9 小时前
【Qwt 7.0 系列】3D 数据可视化 —— OpenGL 高性能三维绘图
qt·3d·qcustomplot·qwt·科学绘图·高性能绘图
满天星83035779 小时前
【Qt】控件(二) (geometry及与frameGeometry的区别)
开发语言·qt
大气的小蜜蜂10 小时前
基于Python+PyQt5+SQLite的药房管理系统实现:事务一致性与界面解耦全流程解析
python·qt·sqlite
尘中远10 小时前
【Qwt 7.0 系列】总体架构解析 —— 从单体到三库模块化的演进
qt·matplotlib·绘图·qwt·科学绘图