gpt4 book ai didi

python - PyQt5循环问题,只有QWebEngineView对象的最后一次迭代有效

转载 作者:行者123 更新时间:2023-12-01 08:46:39 26 4
gpt4 key购买 nike

我之前没有使用 Qt/PyQt 的经验。我只是尝试使用 PyQt 的 Web 引擎功能,将 html 文件文件夹“转换”为 pdf 文档。

如果只有 1 个 html 文件,该代码运行良好,但当有多个 html 文件时它只会为循环中的最后一个文件生成 pdf

我认为这个问题一定与 Qt 的东西、循环、事件等有关 - 但我不知道从哪里开始解决这个问题。正如你所知,我只是使用 Qt 来生成 html->pdf,我对构建 GUI 不感兴趣。

我读到有关在循环末尾使用QApplication.processEvents()可能会解决此问题,但结果是相同的。我尝试在代码中添加 sleep /暂停,也是一样的。

import sys
import os

from PyQt5.QtWidgets import QApplication
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtCore import QDir, QUrl

# read somewhere this is needed to load local html, works without for me though
sys.argv.append("--disable-web-security")
app = QApplication(sys.argv)

iter_num = 0

directory = 'my_webfile_directory'
for filename in os.listdir(directory):
if filename.endswith(".htm") or filename.endswith(".html"):
with open(os.path.join(directory, filename), 'r') as myfile:

print(filename)
raw_html = myfile.read()
# init qt web view
view = QWebEngineView()
view.setHtml(raw_html)

# set to close web view after pdf is created
view.page().pdfPrintingFinished.connect(view.close)
# generate filename
iter_num += 1
outputfilename = str(iter_num) + ".pdf"
outputfullpath = os.path.join(directory, outputfilename)

def save_pdf(finished):
view.page().printToPdf(outputfullpath)
# when web view is ready, save the pdf
view.loadFinished.connect(save_pdf)
# QApplication.processEvents()

app.exec()

最佳答案

我认为QWebEngineView不是线程安全的,因为我能够通过创建要处理的文件队列并使用信号一个接一个地执行来使其一致工作,这是一个演示应用:

import sys
import os

from PyQt5.QtWidgets import QApplication, QMainWindow, QMessageBox
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtCore import QObject, QDir, QUrl, pyqtSignal


class HtmlToPdfConverter(QObject):

queueProcessed = pyqtSignal()

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

self._queue = []
self._current = None

def queue(self, html_file, output_file):
self._queue.append((html_file, output_file))

def process_queue(self):
if self._queue:
raw_html = ''
self._current = self._queue.pop(0)
with open(self._current[0], 'r') as my_file:
raw_html = my_file.read()

view = QWebEngineView()
view.loadFinished.connect(self._get_load_finished_event(view))
view.page().pdfPrintingFinished.connect(self._get_printing_finished_event(view))
view.setHtml(raw_html)
else:
self.queueProcessed.emit()

def _get_load_finished_event(self, view):
def _load_finished(success):
if success:
view.page().printToPdf(self._current[1])
return _load_finished

def _get_printing_finished_event(self, view):
def _printing_finished(file, success):
view.close()
self.process_queue()
return _printing_finished


class App(QApplication):
def __init__(self, sys_argv):
super().__init__(sys_argv)

self.dummy_window = QMainWindow()
self.dummy_window.show()

def generate_pdfs(self, directory):
converter = HtmlToPdfConverter()
converter.queueProcessed.connect(self._queue_processed)

iter_num = 0

for filename in os.listdir(directory):
if filename.endswith(".htm") or filename.endswith(".html"):
iter_num += 1
out_filename = os.path.join(directory, str(iter_num) + ".pdf")
converter.queue(os.path.join(directory, filename), out_filename)

converter.process_queue()

def _queue_processed(self):
QMessageBox.information(self.dummy_window, 'Pdf Generator', 'All PDF files have been generated.')


if __name__ == '__main__':
app = App(sys.argv)
app.generate_pdfs('c:/temp/test')

sys.exit(app.exec_())

关于python - PyQt5循环问题,只有QWebEngineView对象的最后一次迭代有效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53277956/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com