我有一个编写文本的程序,当我单击“编译”按钮时,它将编译为乳胶,转换为pdf并显示在我的应用程序中。 问题是,当我遇到编译错误时,应用程序就会出错,仅此而已。 我想知道是否有可能在不使应用程序崩溃的情况下恢复编译错误。 我尝试使用try / expect,但这不是python错误,因此无法正常工作。
您将需要PDF.js才能查看pdf https://mozilla.github.io/pdf.js/getting_started/#download
Ui:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(841, 481)
self.horizontalLayout = QtWidgets.QHBoxLayout(Dialog)
self.horizontalLayout.setObjectName("horizontalLayout")
self.gridLayout = QtWidgets.QGridLayout()
self.gridLayout.setObjectName("gridLayout")
self.textEdit = QtWidgets.QTextEdit(Dialog)
self.textEdit.setMinimumSize(QtCore.QSize(0, 200))
self.textEdit.setObjectName("textEdit")
self.gridLayout.addWidget(self.textEdit, 0, 0, 1, 1)
self.buttonBox = QtWidgets.QDialogButtonBox(Dialog)
self.buttonBox.setOrientation(QtCore.Qt.Vertical)
self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
self.buttonBox.setObjectName("buttonBox")
self.gridLayout.addWidget(self.buttonBox, 0, 1, 1, 1)
#self.textEdit_2 = QtWidgets.QTextEdit(Dialog)
#self.textEdit_2.setObjectName("textEdit_2")
#self.gridLayout.addWidget(self.textEdit_2, 1, 0, 1, 1)
self.horizontalLayout.addLayout(self.gridLayout)
self.retranslateUi(Dialog)
self.buttonBox.accepted.connect(Dialog.accept)
self.buttonBox.rejected.connect(Dialog.reject)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
app:
import os
import sys
from PyQt5.QtWidgets import QDialog, QPushButton, QWidget, QApplication
from PyQt5 import QtCore, QtWidgets, QtWebEngineWidgets
from sympy import Symbol
import untitled
x=Symbol('x')
class Test(QDialog, untitled.Ui_Dialog):
def __init__(self):
super(Test, self).__init__()
self.setupUi(self)
self.bouton= QPushButton('compile',self)
self.horizontalLayout.addWidget(self.bouton)
self.bouton.clicked.connect(self.crertest)
self.widget = QWidget(self)
self.gridLayout.addWidget(self.widget, 1, 0, 1, 1)
self.t = Window()
lay = QtWidgets.QVBoxLayout(self.widget)
lay.addWidget(self.t)
def crertest(self):
try :
def preambule(*packages):
p = ""
for i in packages:
p = p + "\\usepackage{" + i + "}\n"
return p
start = "\\documentclass[12pt,a4paper,french]{article}\n\\usepackage[utf8]{inputenc}\n"
start = start + preambule('amsmath','graphicx')
start = start + "\\begin{document}\n"
end = "\\end{document}"
body = self.textEdit.toPlainText()
container = start + body + end
file = "mypdf.tex"
if os.path.exists(file):
os.remove(file)
fichier = open("mypdf.tex", "x") #
fichier.write(container)
fichier.close()
instructions = "pdflatex " + file
os.system(instructions)
readpdf = "START " + file[:-4] + ".pdf"
self.t.loadd()
except:
print('Fail')
PDFJS = 'file:///C:/Users/pdf_js/web/viewer.html' #Path too viewer.htlm in your pddf_js folder
PDF = 'file:///C:/Users/mypdf.pdf' #Path to your pdf
class Window(QtWebEngineWidgets.QWebEngineView):
def __init__(self):
super(Window, self).__init__()
self.loadd()
try:
def loadd(self):
self.load(QtCore.QUrl.fromUserInput('%s?file=%s' % (PDFJS, PDF)))
except:
print ('Fail 2')
if __name__ == '__main__':
app = QApplication(sys.argv)
main = Test()
main.show()
app.exec_()
我将这篇文章中的代码用于pdf显示:How to render PDF using pdf.js viewer in PyQt?
就像Texmaker一样的乳胶编辑器。
编辑。
我将程序的一部分编译为乳胶,并在另一个模块中显示pdf。
我在主文件上调用该模块,除了必须两次编译程序才能更新显示内容。 有时是在编译3/4次之后,该错误才出现。 我需要添加一些内容才能运行一次?
compile:test.py
import os
from PyQt5 import QtCore, QtGui, QtWidgets, QtWebEngineWidgets
CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
TMP_DIR = os.path.join(CURRENT_DIR, "tmp")
PDFJS = os.path.join(CURRENT_DIR, "3rdParty/pdfjs-2.2.228-dist/web/viewer.html")
def create_document(content, packages):
lines = (
r"\documentclass[12pt,a4paper,french]{article}",
r"\usepackage[utf8]{inputenc}",
*(r"\usepackage {%s}" % (package,) for package in packages),
r"\begin{document}",
content,
r"\end{document}",
)
return "\n".join(lines)
class PdfViewer(QtWebEngineWidgets.QWebEngineView):
def load_pdf(self, filename):
url = QtCore.QUrl.fromUserInput(
"%s?file=%s" % (QtCore.QUrl.fromLocalFile(PDFJS).toString(), filename)
)
self.load(url)
class Compile:
def __init__(self, parent):
super().__init__()
self.process = QtCore.QProcess(parent)
self.process.readyReadStandardOutput.connect(self.on_readyReadStandardOutput)
self.process.finished.connect(self.on_finished)
self.process.setProgram("pdflatex")
self.basename = "mypdf"
def compile(self,body):
doc = create_document(body, ("amsmath", "graphicx"))
QtCore.QDir().mkpath(TMP_DIR)
self.qfile = QtCore.QFile(os.path.join(TMP_DIR, self.basename + ".tex"))
if self.qfile.open(QtCore.QIODevice.WriteOnly):
self.qfile.write(doc.encode())
self.qfile.close()
self.process.setArguments(
[
"-interaction=nonstopmode",
"-jobname={}".format(self.basename),
"-output-directory={}".format(TMP_DIR),
self.qfile.fileName(),
]
)
self.process.start()
def on_readyReadStandardOutput(self):
print(self.process.readAllStandardOutput().data().decode(), end='')
def on_finished(self):
self.qfile.remove()
致电:
import os
from PyQt5 import QtCore, QtGui, QtWidgets, QtWebEngineWidgets
import test
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.input = QtWidgets.QTextEdit()
self.input.setText('.')
self.a = test.Compile(self)
self.a.compile('.')
self.b = test.PdfViewer()
self.b.load_pdf(your PDF path)
compile_button = QtWidgets.QPushButton(self.tr("Compile"))
lay = QtWidgets.QGridLayout(self)
lay.addWidget(compile_button, 0, 0, 1, 2)
lay.addWidget(self.input, 1, 0)
lay.addWidget(self.b, 1, 1)
lay.setColumnStretch(0, 1)
lay.setColumnStretch(1, 1)
compile_button.clicked.connect(self.call)
def call(self):
self.a.compile(self.input.toPlainText())
self.b.load_pdf(your PDF path)
def main():
import sys
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.showMaximized()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
答案 0 :(得分:1)
很难知道您的问题的错误,因为可能有很多原因,所以我从头开始创建了示例。为此,您必须具有以下文件结构:在脚本的旁边,必须有一个名为3rdParty的文件夹,在其中您必须解压缩从PDF.js下载的文件。
├── 3rdParty
│ └── pdfjs-2.2.228-dist
│ ├── build
│ │ ├── pdf.js
│ │ ├── pdf.js.map
│ │ ├── pdf.worker.js
│ │ └── pdf.worker.js.map
│ ├── LICENSE
│ └── web
│ ├── cmaps
│ ├── compressed.tracemonkey-pldi-09.pdf
│ ├── debugger.js
│ ├── images
│ ├── locale
│ ├── viewer.css
│ ├── viewer.html
│ ├── viewer.js
│ └── viewer.js.map
├── main.py
└── tmp
除了使用os.system()之外,最好使用一种方法来提供有关转换状态的反馈,在这种情况下,请使用QProcess,除了添加更多选项(例如“ -interaction = nonstopmode”,“ -jobname = FILENAME”和“ -output-directory = DIR”(允许没有交互模式),指向文件夹Output和pdf名称:
import os
from PyQt5 import QtCore, QtGui, QtWidgets, QtWebEngineWidgets
CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
TMP_DIR = os.path.join(CURRENT_DIR, "tmp")
PDFJS = os.path.join(CURRENT_DIR, "3rdParty/pdfjs-2.2.228-dist/web/viewer.html")
def create_document(content, packages):
lines = (
r"\documentclass[12pt,a4paper,french]{article}",
r"\usepackage[utf8]{inputenc}",
*(r"\usepackage {%s}" % (package,) for package in packages),
r"\begin{document}",
content,
r"\end{document}",
)
return "\n".join(lines)
class PdfViewer(QtWebEngineWidgets.QWebEngineView):
def load_pdf(self, filename):
url = QtCore.QUrl.fromUserInput(
"%s?file=%s" % (QtCore.QUrl.fromLocalFile(PDFJS).toString(), filename)
)
self.load(url)
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.input = QtWidgets.QTextEdit()
self.output = PdfViewer()
compile_button = QtWidgets.QPushButton(self.tr("Compile"))
lay = QtWidgets.QGridLayout(self)
lay.addWidget(compile_button, 0, 0, 1, 2)
lay.addWidget(self.input, 1, 0)
lay.addWidget(self.output, 1, 1)
lay.setColumnStretch(0, 1)
lay.setColumnStretch(1, 1)
compile_button.clicked.connect(self.compile)
self.process = QtCore.QProcess(self)
self.process.readyReadStandardError.connect(self.on_readyReadStandardError)
self.process.readyReadStandardOutput.connect(self.on_readyReadStandardOutput)
self.process.finished.connect(self.on_finished)
self.process.setProgram("pdflatex")
self.basename = "mypdf"
def compile(self):
doc = create_document(self.input.toPlainText(), ("amsmath", "graphicx"))
QtCore.QDir().mkpath(TMP_DIR)
self.qfile = QtCore.QFile(os.path.join(TMP_DIR, self.basename + ".tex"))
if self.qfile.open(QtCore.QIODevice.WriteOnly):
self.qfile.write(doc.encode())
self.qfile.close()
self.process.setArguments(
[
"-interaction=nonstopmode",
"-jobname={}".format(self.basename),
"-output-directory={}".format(TMP_DIR),
self.qfile.fileName(),
]
)
self.process.start()
def on_readyReadStandardError(self):
print(self.process.readAllStandardError().data().decode(), end='')
def on_readyReadStandardOutput(self):
print(self.process.readAllStandardOutput().data().decode(), end='')
def on_finished(self):
self.qfile.remove()
pdf_filename = os.path.join(TMP_DIR, self.basename + ".pdf")
self.output.load_pdf(pdf_filename)
def main():
import sys
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.showMaximized()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
注意::try-except仅处理python代码引发的异常(而不是错误),而不处理其他程序(例如pdflatex)引发的异常。对于QProcess,readyReadStandardOutput和readyReadStandardError信号分别通知程序中是否有stdout和stderr信息(在本例中为pdflatex),可以分别使用readAllStandardOutput()和readAllStandardError()方法进行检索。该信息将打印在控制台上