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

子类化QPdfView实现PDF矩形绘制:绘制内容需切换页面才显示问题排查

问题分析与解决

你的猜测方向没错,但直接导致矩形无法实时显示的核心原因是重绘触发对象错误,而非单纯是绘制到控件上的问题:

  • 你当前调用self.update()触发的是整个QPdfView控件的重绘,但实际负责显示PDF内容的是它的子部件viewport,PDF渲染会优先覆盖viewport的绘制内容,普通的控件重绘无法触发viewport的实时刷新,只有切换页面时PDF的渲染流程会顺带触发viewport重绘,这才让你看到矩形。
  • 当然,你确实是把矩形绘制在控件的viewport上,而非修改PDF文件本身,但这只是“矩形不会保存到PDF”的原因,不是实时显示的问题。

代码修改方案

只需要把所有self.update()替换为self.viewport().update(),同时可以给矩形加上更明显的样式(比如红色边框),避免被PDF内容淹没:

FREE_STATE = 1
BUILDING_SQUARE = 2
BEGIN_SIDE_EDIT = 3
END_SIDE_EDIT = 4

class customQPdfView(QPdfView):
    def __init__(self,parent):
        super().__init__(parent)
        
        self.setGeometry(30, 30, 600, 400)
        self.begin = QPoint()
        self.end = QPoint()
        self.state = FREE_STATE
        # 定义矩形绘制的画笔,让边框更明显
        self.rect_pen = QPen(Qt.red, 2)
    
    def paintEvent(self, event):
        super().paintEvent(event)
        painter = QPainter(self.viewport())
        painter.setPen(self.rect_pen)
        painter.drawRect(QRect(self.begin, self.end))

    def mousePressEvent(self, event):
        print('press')
        if not self.begin.isNull() and not self.end.isNull():
            p = event.pos()
            y1, y2 = sorted([self.begin.y(), self.end.y()])
            if y1 <= p.y() <= y2:
                if abs(self.begin.x() - p.x()) <= 3:
                    self.state = BEGIN_SIDE_EDIT
                    return
                elif abs(self.end.x() - p.x()) <= 3:
                    self.state = END_SIDE_EDIT
                    return
        self.state = BUILDING_SQUARE
        self.begin = event.pos()
        self.end = event.pos()
        self.viewport().update()

    def applye_event(self, event):
        if self.state == BUILDING_SQUARE:
            self.end = event.pos()
        elif self.state == BEGIN_SIDE_EDIT:
            self.begin.setX(event.x())
        elif self.state == END_SIDE_EDIT:
            self.end.setX(event.x())

    def mouseMoveEvent(self, event):
        print('move')
        self.applye_event(event)
        self.viewport().update()

    def mouseReleaseEvent(self, event):
        print('release')
        self.applye_event(event)
        self.state = FREE_STATE
        self.viewport().update()

额外说明

如果后续需要把矩形永久保存到PDF文件中,你需要使用QPdfWriter或PDF处理库(如PyPDF2)操作PDF文档本身——当前的绘制只是临时显示在界面上,不会修改原始PDF文件。

内容的提问来源于stack exchange,提问作者ScottyCov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 14:15:14