QtWebEngine - Synchroneous printToPdf
-
wrote on 13 May 2021, 18:42 last edited by
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
-
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
wrote on 13 May 2021, 19:56 last edited by JonB@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.
-
-
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
wrote on 13 May 2021, 20:04 last edited by@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")
-
wrote on 13 May 2021, 20:16 last edited by
Thank you so very much @JonB and @eyllanesc! I struggled a lot with this and you both helped tremendously.
-
Thank you so very much @JonB and @eyllanesc! I struggled a lot with this and you both helped tremendously.
wrote on 13 May 2021, 20:25 last edited by JonB@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. -
@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.wrote on 13 May 2021, 22:14 last edited by@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.
-
wrote on 17 May 2021, 15:32 last edited by deleted457
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.
-
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.
wrote on 17 May 2021, 15:47 last edited by@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. -
@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.wrote on 17 May 2021, 17:13 last edited by@JonB Thank you! I'll see into it. :)
1/9