简体   繁体   中英

QWebEngineView fails to render PDF embedded in HTML

I'm writing a Python script for an MDI-based PyQt5 application, where the windows use the new QWebEngineView to render some HTML that embeds a PDF in an iFrame. The HTML is a custom-generated string and the PDF is a local file.

The HTML is a locally stored template that my code loads and then alters to insert a variable:

<!DOCTYPE html>
<html>
  <head>
    <title>Title</title>
  </head>
  <body>
    <iframe src="$PDF">
    </iframe>
  </body>
</html>

$PDF is subbed in as a string like: file:///local/path/to/document.pdf

Here's my Python script so far:

import os, sys
from PyQt5.QtCore import QUrl
from PyQt5.QtWidgets import QApplication, QMainWindow, QMdiArea, QAction, QMdiSubWindow
from PyQt5 import QtWebEngineWidgets

class MDIWindow(QMainWindow):

    def __init__(self):
        super().__init__()

        self.mdi = QMdiArea()
        self.setCentralWidget(self.mdi)
        bar = self.menuBar()
        file = bar.addMenu("File")
        file.addAction("New")
        file.addAction("cascade")
        file.addAction("Tiled")
        file.triggered[QAction].connect(self.Window)
        self.setWindowTitle("MDI Application")

    def Window(self, p):
        if p.text() == "New":
            sub = QMdiSubWindow()
            view = QtWebEngineWidgets.QWebEngineView()
            settings = view.settings()
            settings.setAttribute(QtWebEngineWidgets.QWebEngineSettings.PluginsEnabled, True)
            CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
            pdf_path = "file://" + os.path.join(CURRENT_DIR, "test.pdf")
            template = os.path.join(CURRENT_DIR, "test.html")
            with open(template, 'rt') as f:
                text = ''.join(f.readlines())
                html = text.replace('$PDF', pdf_path)
            view.setHtml(html, QUrl("file://"))
            sub.setWidget(view)
            sub.setWindowTitle("Test")
            self.mdi.addSubWindow(sub)
            sub.show()

        if p.text() == "cascade":
            self.mdi.cascadeSubWindows()

        if p.text() == "Tiled":
            self.mdi.tileSubWindows()

app = QApplication([])
mdi = MDIWindow()
mdi.show()
app.exec_()

Most of this script works fine - it creates the main window, receives a menu bar command to create a document window, creates the document window, and loads the HTML. All good.

The problem is that the embedded PDF won't load. All I get is a gray surface.

Further observations:

  • Any HTML visual elements inserted into the page are correctly rendered.

  • Changing the resource type to an image, such as a PNG, results in the resource being correctly rendered. It's just PDFs that are problematic.

  • If I change the file URL to something else, I get warnings about a dead link. So it's clearly trying to load the PDF.

  • The actual PDF does not matter - I've tried several different ones with the same result.

  • The gray surface provides a context menu with Reload, Save Page, and View Source. Reload apparently does cause the page to refresh (it blinks for a brief moment) but produces the same result. Save Page and View Source do nothing.

Any ideas? Thanks in advance.

It seems to be a Qt WebEngine bug( QTBUG-84340 ) since I have implemented the code with Qt 5.15 (and PyQt5 5.15 and PyQtWebEngine 5.15) and it does not load the pdf. Instead I have tested it with PyQt5 5.14.2 and PyQtWebEngine 5.14.0 works correctly, so I recommend you install those packages:

python -m pip install pyqt5==5.14.2 pyqtwebengine==5.14.0

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM