You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在QPdfView内绘制随PDF文档滚动的矩形?

在QPdfView中绘制随文档滚动的高亮矩形

问题描述

使用Qt 5.15的QPdfView类创建PDF显示控件,需要用矩形高亮PDF中的指定文字,已通过QPdfSearchModel获取到文字的文档坐标系坐标。但继承QPdfView重写paintEvent绘制的矩形固定在视口位置,无法随PDF滚动同步移动。

核心原因

QPdfView继承自QAbstractScrollArea,直接在视口上绘制的坐标是视口本地坐标系,而QPdfSearchModel返回的是PDF文档自身的坐标系矩形,二者未关联缩放比例和滚动偏移,导致矩形位置固定不随文档滚动。

解决方案

需要将文档坐标系中的文字矩形,转换为当前视口的显示坐标系,核心步骤:

  • 获取当前视图的缩放因子、滚动偏移量
  • 将文档中文字的边界矩形转换为视口坐标
  • 仅绘制当前可见区域内的高亮矩形,避免无效渲染

修改后的代码示例

#include <QPdfView>
#include <QPdfDocument>
#include <QPdfPage>
#include <QPainter>
#include <QScrollBar>

class QPdfViewCustom : public QPdfView
{
    Q_OBJECT
public:
    explicit QPdfViewCustom(QWidget* parent = nullptr) : QPdfView(parent) {}

    // 设置需要高亮的内容:页面索引 + 文档坐标系矩形
    void setHighlightRects(const QList<QPair<int, QRectF>>& rects) {
        m_highlightRects = rects;
        viewport()->update(); // 触发视口重绘
    }

protected:
    void paintEvent(QPaintEvent *event) override
    {
        QPdfView::paintEvent(event); // 先绘制PDF原内容

        if (!document())
            return;

        QPainter painter(viewport());
        painter.setPen(Qt::red);
        painter.setBrush(QColor(255, 0, 0, 50)); // 半透明红色高亮,避免遮挡文字

        const qreal scale = zoomFactor();
        const int vOffset = verticalScrollBar()->value();
        const int hOffset = horizontalScrollBar()->value();

        for (const auto& item : m_highlightRects) {
            int pageIdx = item.first;
            QRectF docRect = item.second;

            // 获取当前页面在视口的显示区域
            QRect pageViewRect = pageViewport(pageIdx);
            // 只处理当前可见区域内的页面高亮
            if (pageViewRect.intersects(event->rect())) {
                // 转换文档坐标到视口坐标:页面偏移 + 缩放后的矩形尺寸 - 滚动偏移
                QRectF viewRect = QRectF(
                    pageViewRect.x() + docRect.x() * scale - hOffset,
                    pageViewRect.y() + docRect.y() * scale - vOffset,
                    docRect.width() * scale,
                    docRect.height() * scale
                );
                painter.drawRect(viewRect);
            }
        }
    }

private:
    QList<QPair<int, QRectF>> m_highlightRects; // 存储高亮内容的页面和矩形信息
};

关键细节说明

  • pageViewport(pageIdx):获取指定页面在视口上的显示矩形,包含页面的初始位置偏移
  • zoomFactor():将文档坐标系的尺寸转换为视口的实际显示尺寸
  • 滚动条value():减去滚动偏移量,确保矩形跟随文档滚动移动
  • 可见区域判断:只绘制与当前重绘区域相交的高亮矩形,提升渲染性能

Qt PDF模块说明

Qt PDF模块提供了一套用于查看、渲染PDF文档的类,支持文档导航、文本搜索、缩放显示、页面旋转等核心功能,可快速构建PDF阅读器类应用。


内容的提问来源于stack exchange,提问作者Андрей Петров

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 08:45:29