2

I'm trying to get some simple html to be saved onto a pdf document using PyQt5. The webpage renders properly, using the show() command I can get a window showing me the web content in question, however trying to print it to pdf only results in blank pdfs.

This is on python 3.6 and as of posting this question I have the current PyQt5 version. (Windows 10, 64 Bit)

There's a lot of older questions to this already on stackoverflow, but I found most of them use functions that no longer exist.

The problematic code follows:

from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEngineSettings
from PyQt5 import QtWidgets
from PyQt5.QtPrintSupport import QPrinter
from PyQt5 import QtCore
[...]
    app = QtWidgets.QApplication(sys.argv)
    QWebEngineSettings.globalSettings().setAttribute(QWebEngineSettings.PluginsEnabled, True)
    QWebEngineSettings.globalSettings().setAttribute(QWebEngineSettings.ScreenCaptureEnabled, True)
    loader = QWebEngineView()
    #loader.setAttribute(QtCore.Qt.WA_DontShowOnScreen, True)
    loader.setAttribute(QtCore.Qt.WA_DeleteOnClose, True)
    loader.setZoomFactor(1)
    loader.setHtml(webpage)


    printer = QPrinter()
    printer.setPageSize(QPrinter.A4)
    printer.setOutputFormat(QPrinter.PdfFormat)
    printer.setOutputFileName("test.pdf")
    printer.setOrientation(QPrinter.Portrait)
    printer.setFullPage(True)

    def emit_pdf(finished):
        loader.show()
        loader.render(printer)
        if self.open_on_complete:
            import webbrowser
            webbrowser.open("test.pdf")

        #app.exit()
    loader.loadFinished.connect(emit_pdf)

    app.exec()
ekhumoro
  • 115,249
  • 20
  • 229
  • 336
Berserker
  • 1,112
  • 10
  • 26

1 Answers1

3

There is no need to use use QPrinter in Qt5, because QWebEnginePage has a dedicated printToPdf method:

import sys
from PyQt5 import QtCore, QtWidgets, QtWebEngineWidgets

app = QtWidgets.QApplication(sys.argv)
loader = QtWebEngineWidgets.QWebEngineView()
loader.setZoomFactor(1)
loader.page().pdfPrintingFinished.connect(
    lambda *args: print('finished:', args))
loader.load(QtCore.QUrl('https://en.wikipedia.org/wiki/Main_Page'))

def emit_pdf(finished):
    loader.show()
    loader.page().printToPdf("test.pdf")

loader.loadFinished.connect(emit_pdf)

app.exec()

There's also a print method that will render to a printer, if you really want that.

ekhumoro
  • 115,249
  • 20
  • 229
  • 336
  • I did try the printtopdf in the past, and then it didn't even give me a file at all. I retried it now and it did work, so maybe I had a bug somewhere else during my attempts. Anyway, thank you for reminding me to check that out again, it does work now. Still a bit confused as to why it is blank in the first place, though. – Berserker Jan 26 '18 at 01:55
  • hey, im a little late, but can you tell me what the purpose of the "finished" argument in the emit_pdf function is? i dont understand – Flying Thunder Apr 05 '19 at 07:55
  • @FlyingThunder [QWebEngineView.loadFinished](https://doc.qt.io/qt-5/qwebengineview.html#loadFinished). – ekhumoro Apr 05 '19 at 18:19
  • what if I want to use a Html template from my computer and I want the contents of Html page to be dynamic? – manjy Apr 14 '19 at 06:55