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(); 获取到要刷新的区域

 

        

相关推荐

  1. QT 的 blockSignals(true) 的作用范围

    2024-01-28 16:06:02       24 阅读
  2. 使用QT实现的RSS新闻阅读器

    2024-01-28 16:06:02       36 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-01-28 16:06:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-28 16:06:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-28 16:06:02       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-28 16:06:02       20 阅读

热门阅读

  1. STM32F407移植OpenHarmony笔记2

    2024-01-28 16:06:02       35 阅读
  2. 数据结构和线程池

    2024-01-28 16:06:02       34 阅读
  3. 设计模式六(模板方法模式)

    2024-01-28 16:06:02       32 阅读
  4. bash 5.2中文修订5

    2024-01-28 16:06:02       29 阅读
  5. 阻抗的简介

    2024-01-28 16:06:02       31 阅读
  6. 计算机网络(第六版)复习提纲14

    2024-01-28 16:06:02       32 阅读
  7. react 什么是h函数

    2024-01-28 16:06:02       33 阅读
  8. linux 内核对多播报文的处理

    2024-01-28 16:06:02       31 阅读