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

如何在PyQt5的QWebEngineView中显示字节流格式PDF?

解决PyQt5 QWebEngineView加载PDF字节流的问题

你尝试用QtCore.QUrl.fromEncoded()加载PDF字节流失败,是因为这个方法的作用是解析编码后的URL字符串,而非直接加载文件内容字节流。要实现从字节流加载PDF到QWebEngineView,有两种可行方案:

方案一:使用Data URI(最简单直接)

将PDF字节流编码为Base64格式,构造符合Data URI规范的字符串,直接让QWebEngineView加载这个URI即可。

修改后的完整代码

from PyQt5 import QtWidgets
from PyQt5 import QtCore
from PyQt5 import QtWebEngineWidgets
import sys
import base64

application = QtWidgets.QApplication(sys.argv)
window = QtWidgets.QWidget()
window_layout = QtWidgets.QGridLayout()

# 模拟从数据库读取的PDF字节流(这里用本地文件演示)
PDF_PATH = "D:\\export.pdf"
with open(PDF_PATH, "rb") as f:
    PDF_as_bytes = f.read()

# 将字节流转为Base64编码的字符串
pdf_base64 = base64.b64encode(PDF_as_bytes).decode("utf-8")
# 构造Data URI
data_uri = f"data:application/pdf;base64,{pdf_base64}"

engine = QtWebEngineWidgets.QWebEngineView()
engine.setMinimumSize(500, 500)
engine_settings = engine.settings()
engine_settings.setAttribute(QtWebEngineWidgets.QWebEngineSettings.PluginsEnabled, True)
engine_settings.setAttribute(QtWebEngineWidgets.QWebEngineSettings.ShowScrollBars, True)
engine_settings.setAttribute(QtWebEngineWidgets.QWebEngineSettings.PdfViewerEnabled, True)

# 加载Data URI
engine.load(QtCore.QUrl.fromUserInput(data_uri))

window_layout.addWidget(engine)
window.setLayout(window_layout)
window.show()
application.exec()

关键说明

  • base64.b64encode()把PDF字节流转成Base64编码的字节串,再用decode("utf-8")转为字符串
  • Data URI格式为data:application/pdf;base64,<Base64编码内容>,QWebEngineView原生支持这种格式加载PDF

方案二:自定义URL Scheme Handler(适合复杂场景)

如果需要频繁从字节流加载PDF,或者要处理动态生成的PDF内容,可以自定义一个URL Scheme Handler,注册专属Scheme(比如pdfstream://),当加载该Scheme的URL时,返回对应的字节流数据。

代码示例

from PyQt5 import QtWidgets
from PyQt5 import QtCore
from PyQt5 import QtWebEngineWidgets
import sys

class PdfStreamHandler(QtWebEngineWidgets.QWebEngineUrlSchemeHandler):
    def __init__(self, pdf_bytes, parent=None):
        super().__init__(parent)
        self._pdf_bytes = pdf_bytes

    def requestStarted(self, request):
        # 创建响应
        response = QtWebEngineWidgets.QWebEngineUrlRequestJob.Response()
        response.setHeader(b"Content-Type", b"application/pdf")
        response.setHeader(b"Content-Length", str(len(self._pdf_bytes)).encode())
        # 写入字节流数据
        request.reply(b"application/pdf", self._pdf_bytes)

application = QtWidgets.QApplication(sys.argv)

# 注册自定义Scheme
scheme = QtCore.QUrlScheme(b"pdfstream")
scheme.setFlags(QtCore.QUrlScheme.SecureScheme | QtCore.QUrlScheme.LocalScheme)
QtCore.QUrlScheme.registerScheme(scheme)

window = QtWidgets.QWidget()
window_layout = QtWidgets.QGridLayout()

# 模拟从数据库读取的PDF字节流
PDF_PATH = "D:\\export.pdf"
with open(PDF_PATH, "rb") as f:
    PDF_as_bytes = f.read()

engine = QtWebEngineWidgets.QWebEngineView()
engine.setMinimumSize(500, 500)
engine_settings = engine.settings()
engine_settings.setAttribute(QtWebEngineWidgets.QWebEngineSettings.PluginsEnabled, True)
engine_settings.setAttribute(QtWebEngineWidgets.QWebEngineSettings.ShowScrollBars, True)
engine_settings.setAttribute(QtWebEngineWidgets.QWebEngineSettings.PdfViewerEnabled, True)

# 添加自定义Handler
handler = PdfStreamHandler(PDF_as_bytes)
engine.page().profile().installUrlSchemeHandler(b"pdfstream", handler)

# 加载自定义Scheme的URL
engine.load(QtCore.QUrl("pdfstream://local/pdf"))

window_layout.addWidget(engine)
window.setLayout(window_layout)
window.show()
application.exec()

关键说明

  • 自定义PdfStreamHandler继承自QWebEngineUrlSchemeHandler,重写requestStarted方法处理请求并返回PDF字节流
  • 注册自定义Scheme时要设置合适的Flags,确保QWebEngineView信任该Scheme
  • 加载时使用自定义Scheme的URL(比如pdfstream://local/pdf),Handler会自动返回对应的字节流

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 03:35:44