PySide6无法显示PDF高亮标记,网页浏览器可正常显示
PySide6 PDF查看器无法显示高亮批注的解决方案
问题背景
基于PySide6开发PDF展示应用,使用Qt官方PDFViewer示例代码,同一PDF在Chrome中正常显示高亮/批注,但应用内加载时高亮完全消失。曾尝试WebView方案,但无法获取当前页码。
截图对比:
- 应用内显示(无高亮):

- Chrome内显示(正常高亮):

可行解决方案
1. 启用Qt PDF模块的批注加载与渲染
Qt默认可能不加载所有批注类型,需手动开启相关选项:
from PySide6.QtPdf import QPdfDocument, QPdfPageRenderer # 初始化文档时启用批注加载 doc = QPdfDocument() doc.setLoadOptions(QPdfDocument.LoadOption.IncludeAnnotations) doc.load("target.pdf") # 渲染页面时包含批注 renderer = QPdfPageRenderer(doc) # 第二个参数为渲染分辨率,按需调整 render_job = renderer.renderPage( page_num, 300, QPdfPageRenderer.RenderFlag.IncludeAnnotations )
如果使用官方示例的PdfViewer类,找到其中初始化QPdfDocument和渲染页面的代码块,添加上述选项即可。
2. 自定义绘制高亮批注
如果Qt默认渲染不兼容你的高亮格式(比如第三方工具生成的特殊高亮),可以手动解析并绘制:
def paintEvent(self, event): painter = QPainter(self) # 保留原示例的PDF页面渲染逻辑 # ... # 遍历当前页面的所有批注 annotations = self.document().pageAnnotations(self.current_page) for annot in annotations: if annot.type() == QPdfAnnotation.Type.Highlight: # 遍历高亮的所有四边形区域 for quad in annot.highlightQuads(): # 将PDF页面坐标转换为控件显示坐标(需根据你的缩放逻辑调整) page_size = self.document().pageSize(self.current_page) display_rect = self.viewport().rect() render_rect = QRectF( quad.boundingRect().x() * display_rect.width() / page_size.width(), quad.boundingRect().y() * display_rect.height() / page_size.height(), quad.boundingRect().width() * display_rect.width() / page_size.width(), quad.boundingRect().height() * display_rect.height() / page_size.height() ) # 绘制半透明黄色高亮 painter.fillRect(render_rect, QColor(255, 255, 0, 80))
3. 修复WebView的页码获取问题
如果想改用WebView方案,可通过注入JavaScript获取当前页码:
from PySide6.QtWebEngineWidgets import QWebEngineView from PySide6.QtCore import QUrl web_view = QWebEngineView() web_view.load(QUrl.fromLocalFile("target.pdf")) # 定义获取页码的函数 def fetch_current_page(): # 适配不同PDF渲染内核的JS代码 js_code = """ function getCurrentPage() { // 适配Chrome内核的PDFViewer if (window.PDFViewerApplication) { return PDFViewerApplication.page + 1; } // 适配embed标签的渲染模式 const embedEl = document.querySelector('embed'); return embedEl ? embedEl.getPageNumber() : null; } getCurrentPage(); """ web_view.page().runJavaScript(js_code, callback=lambda page: print(f"当前页码:{page}")) # 页面加载完成后自动触发获取 web_view.loadFinished.connect(fetch_current_page)
内容的提问来源于stack exchange,提问作者Muhammad Rehan
相关产品推荐
相关产品推荐

