Unsolved QtWebEngine - Synchroneous printToPdf
-
Hi.
I'm writing a bit of code to print pages to pdf and then process the generated pdf.
I can't understand how to wait for printToPdf to finish and the file to be created before continuing my script that processes the generated pdf.
Since printToPdf seems to be fired in a thread, my code coming after always gets fired first before the pdf is generated. Is there a way to circumvent this?
Here is an example of my code:
class WebEngineViewForPDF(QWebEngineView): def __init__(self, link, file, *args, **kwargs): super(WebEngineViewForPDF, self).__init__(*args, **kwargs) self.link = link self.file = file self.load_page() def load_page(self): self.page().loadFinished.connect(self.generatepdf) self.page().load(QUrl(self.link)) def pdf_printed(self): print("PDF has been generated") def generatepdf(self): self.page().pdfPrintingFinished.connect(self.pdf_printed) self.page().printToPdf(self.file) app = QApplication(sys.argv) WebEngine = WebEngineViewForPDF("http://www.google.ca", "test.pdf") if os.path.isfile("test.pdf"): print("File exists, process pdf.") else: print("File does not exist, impossible to process.") sys.exit(app.exec_())
Any help would be greatly appreciated!
Thanks,
MisterD4N
-
@MisterD4N said in QtWebEngine - Synchroneous printToPdf:
I can't understand how to wait for printToPdf to finish and the file to be created before continuing my script that processes the generated pdf.
There are usually two approaches.
-
The neatest way is to have the code you want to continue with be called from your
self.pdf_printed
slot. But I know that means changing the code to do so. -
If you really want to wait and make it synchronous, because that does leave the script processing logic as-is, use a
QEventLoop.exec()
andQEventLoop.exit
/quit()
when thepdfPrintingFinished
is emitted.
-
-
@MisterD4N If you are only using Qt to generate a pdf file (assuming you are not using other elements of the GUI since the OP does not give a specific context) then it is not necessary to use QWebEngineView but rather QWebEnginePage, also you should not pass what exec returns to sys .exit() as the latter will close the entire application.
import sys from PySide2.QtCore import QCoreApplication, QUrl from PySide2.QtWidgets import QApplication from PySide2.QtWebEngineWidgets import QWebEnginePage class PDFPage(QWebEnginePage): def __init__(self, url, filename): super(PDFPage, self).__init__() self.url = QUrl.fromUserInput(url) self.filename = filename self.pdfPrintingFinished.connect(self.pdf_printing_finished) self.loadFinished.connect(self.load_finished) def start(self): self.load(self.url) def pdf_printing_finished(self): QCoreApplication.quit() def load_finished(self, ok): if ok: self.printToPdf(self.filename) else: QCoreApplication.exit(-1) def pdf_from_url(url, filename): app = QApplication(sys.argv) page = PDFPage(url, filename) page.start() ret = app.exec_() return ret == 0 sucess = pdf_from_url("http://www.google.ca", "test.pdf") if sucess: print("PDF has been generated")
-
Thank you so very much @JonB and @eyllanesc! I struggled a lot with this and you both helped tremendously.
-
@MisterD4N
I hadn't noticed all you seem to want is a standalone script, to exit as soon as the printing is done. Your "script" is external to this program. My suggestions apply when the further processing is in the python Qt program. You should follow what @eyllanesc has suggested to exit, not just wait. The same principle applies though in terms of how to make it synchronous. -
@JonB You are right. The further processing is in the Qt Program. @eyllanesc answer pointed me in the right direction, I think. Now I'm trying to make it work with QEventLoop.
-
Hi guys, i was able to make it work with QEventLoop. Any pointers on how to make it work inside a thread? I'm at a lost again.
-
@MisterD4N
You can/should only doQWebEngine
-y things in the main UI thread.Compared to when I did synchronous PDF printing years ago when
QWebEngine
was the only way to go, I believe Qt now has PDF output support through new classes. If that helps any. -
@JonB Thank you! I'll see into it. :)