PyQt5无界面HTML转PDF:回调未触发及事件循环问题
解决QtWebEngineWidgets HTML转PDF时回调不触发且需自动退出的问题
你的问题核心在于事件循环过早退出:当你在emit_pdf里直接调用app.exit(0),事件循环会立刻终止,导致printToPdf的异步打印操作还没完成就被打断,回调自然没机会执行;而去掉exit后,事件循环一直运行,打印能正常完成,但程序会卡住等待手动关闭。
我们只需要把退出事件循环的逻辑延迟到PDF打印完成后,确保所有异步任务都执行完毕再退出。下面是修改后的完整代码:
import sys from PyQt5 import QtCore, QtWidgets, QtWebEngineWidgets from tempfile import gettempdir from pathlib import Path def printhtmltopdf(html_in, callback): tfile = Path(gettempdir(), 'printhtmltopdf.html') with open(tfile, 'wb') as tempf: tempf.write(html_in) app = QtWidgets.QApplication(sys.argv) loader = QtWebEngineWidgets.QWebEngineView() loader.setZoomFactor(1) # 打印完成后统一处理:触发用户回调 + 退出事件循环 def on_pdf_print_finished(file_path, success): print('finished:', file_path, success) callback(file_path, success) # 执行你传入的回调函数 app.exit(0) # 确认打印完成后再退出 loader.page().pdfPrintingFinished.connect(on_pdf_print_finished) def emit_pdf(page_loaded_success): if page_loaded_success: # 确保页面加载成功再启动打印 loader.page().printToPdf(callback) loader.loadFinished.connect(emit_pdf) loader.load(QtCore.QUrl().fromLocalFile(str(tfile))) app.exec()
关键调整说明:
- 把
app.exit(0)从页面加载完成的回调移到了pdfPrintingFinished信号的处理函数中,保证只有当PDF打印任务彻底完成后,才会退出事件循环。 - 增加了页面加载成功的判断(
if page_loaded_success),避免页面还没渲染完成就触发打印,导致PDF内容异常。 - 用命名函数
on_pdf_print_finished替代了原来的lambda,让逻辑更清晰,同时确保用户传入的回调能被正确触发。
修改后,程序会自动完成HTML加载、PDF渲染打印,触发你的回调函数,最后自动退出全程无需用户交互。
内容的提问来源于stack exchange,提问作者Dick Kniep
相关产品推荐
相关产品推荐

