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

如何将PDF.js渲染完成信号关联到PyQt5.QtWebEngineWidgets?

解决PyQt5 QWebEngineView结合PDF.js捕获渲染完成事件的问题

核心问题分析

你遇到的renderContext is not defined错误,是因为直接引用了未初始化的PDF.js内部变量。PDF.js的渲染状态需要通过官方API监听,而非直接访问未暴露的内部对象。另外,要实现JS渲染完成事件触发Python函数,必须通过QWebChannel建立JS与Python的通信桥接。

解决方案步骤

1. 准备PDF.js资源

确保已下载PDF.js预构建包(包含web/viewer.html及相关js/css文件),后续加载时要正确指定资源路径。

2. 用QWebChannel建立JS-Python通信

通过QWebChannel将Python的回调对象暴露给JS,让PDF.js的渲染完成事件可以直接调用Python函数。

3. 正确监听PDF.js的渲染完成事件

在PDF.js页面中,通过官方API监听页面渲染完成事件,避免使用未定义的内部变量。

完整代码示例

from PyQt5.QtWidgets import QApplication, QMainWindow, QWebEngineView
from PyQt5.QtWebChannel import QWebChannel
from PyQt5.QtCore import QObject, pyqtSlot, QUrl
import sys

class PdfRenderCallback(QObject):
    @pyqtSlot()
    def on_render_finished(self):
        # 渲染完成后执行的逻辑写在这里
        print("PDF页面渲染完成!")
        # 示例:触发其他自定义函数
        # self.your_another_function()

class PdfViewer(QWebEngineView):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.callback = PdfRenderCallback()
        # 初始化通信通道
        self.channel = QWebChannel()
        self.channel.registerObject("pyCallback", self.callback)
        self.page().setWebChannel(self.channel)
        
        # 替换为你的PDF.js路径和目标PDF文件路径
        target_pdf = "file:///your/path/to/test.pdf"
        viewer_url = QUrl(f"file:///your/path/to/pdfjs/web/viewer.html?file={target_pdf}")
        self.load(viewer_url)
        
        # 页面加载完成后注入监听JS
        self.loadFinished.connect(self.inject_render_listener)

    def inject_render_listener(self):
        # 注入JS代码监听PDF渲染完成事件
        js_code = """
        // 等待PDFViewer初始化完成
        document.addEventListener('webviewerloaded', function() {
            const viewer = window.PDFViewerApplication;
            // 监听所有页面渲染完成事件
            viewer.eventBus.on('pagesloaded', function() {
                // 调用Python端的回调函数
                window.pyCallback.on_render_finished();
            });
        });
        """
        self.page().runJavaScript(js_code)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = QMainWindow()
    viewer = PdfViewer()
    window.setCentralWidget(viewer)
    window.show()
    sys.exit(app.exec_())

关键细节说明

  • webviewerloaded事件:PDF.js的viewer页面加载完成后触发,确保能获取到PDFViewerApplication实例。
  • pagesloaded事件:PDF所有页面渲染完成后触发,对应你需要的“渲染完成”状态。
  • QWebChannel作用:将Python的回调对象暴露给JS,JS通过window.pyCallback调用Python方法。

常见问题排查

  • 若出现路径错误,检查PDF.js资源路径和PDF文件路径是否为标准file://协议格式。
  • 不同PDF.js版本的事件名称可能有差异,旧版可尝试监听documentloaded事件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 18:25:33