在 PyQt5 中显示 MathJax 闪烁和状态栏
MathJax flickering and statusbar showing in PyQt5
对于一个学校项目,我们应该制作一个简单的计算器。该项目的目标是教授 github、团队合作、测试、文档和所有爵士乐。这与计算器无关。然而,我和我的团队决定更进一步,我们想创建一个实时显示数学表达式的计算器。
我设法找到了一种方法:使用 PyQt5 及其 QWebEngineView,我能够显示一个简单的网页,并且,使用 javascript,我能够使用 MathJax 实时显示一个方程。但是,也有一些问题:
输入任何数字后,首先,显示屏下方会出现一个状态栏(瞬间),如下所示:
但这还不是全部 - 在最终数字出现之前,首先会显示原始乳胶代码几分之一秒,然后是分数的 HTMLPreview 版本,只有在所有这些之后才会显示最终渲染.
这是 python x javascript 部分:
from PyQt5.QtWidgets import *
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtGui import QFont
import sys
import time
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWebEngineWidgets import QWebEngineView
class Ui_s_cals(object):
def __init__(self):
self.content=["10","+","10"]
def setupUi(self, s_cals):
s_cals.setObjectName("s_cals")
s_cals.resize(300, 500)
s_cals.setWindowTitle("Calculator")
self.display = QWebEngineView(s_cals)
self.display.setGeometry(QtCore.QRect(20, 10, 300, 60))
self.pushButton_n0 = QtWidgets.QPushButton(s_cals)
self.pushButton_n0.setGeometry(QtCore.QRect(80, 400, 61, 61))
self.pushButton_n0.setObjectName("pushButton_n0")
self.pushButton_n0.setText("0")
self.pushButton_n0.clicked.connect(lambda:self.print("0"))
def print(self,number):
self.content.append(number)
print(self.content)
#self.output1.setText(''.join(self.content))
temp=''.join(self.content)
self.expression=temp
self.pageSource = '''
<html><head>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script></script><script>MathJax.Hub.Config({{
jax: ["input/TeX","output/HTML-CSS"],
displayAlign: "left"
}});</script>
</head>
<body>
<p><mathjax style="font-size:1em">$${expression}$$</mathjax></p>
</body></html>
'''.format(expression=self.expression)
self.display.setHtml(self.pageSource)
class Main(QMainWindow):
def __init__(self):
super().__init__()
self.ui = Ui_s_cals()
self.ui.setupUi(self)
self.show()
def main():
calc = QApplication(sys.argv)
instance = Main()
sys.exit(calc.exec_())
if __name__ == '__main__':
start = time.time()
main()
print(time.time() - start)
我花了好几个小时寻找答案。我尝试将 body 的可见性设置为隐藏,然后在 mathjax 完成渲染后通过脚本使其可见,但它没有用。
我尝试了关于堆栈溢出的所有答案,但是 none 的答案指望我在 python 脚本中使用它,这可能是问题所在。如果您知道实时显示方程式的不同方式。
您不需要更改整个页面内容来呈现新的表达式,而是可以使用 QWebEnginePage.runJavaScript
方法。看看input-tex2chtml.html example in MathJax-demos-web
演示:
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWebEngineWidgets import QWebEngineView
html = """
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width">
<title>MathJax v3 with interactive TeX input and HTML output</title>
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js"></script>
<script>
function convert(input) {
output = document.getElementById('output');
output.innerHTML = '';
MathJax.texReset();
var options = MathJax.getMetricsFor(output);
options.display = true;
MathJax.tex2chtmlPromise(input, options).then(function (node) {
output.appendChild(node);
MathJax.startup.document.clear();
MathJax.startup.document.updateDocument();
}).catch(function (err) {
output.appendChild(document.createTextNode(err.message));
});
}
</script>
<style>
body, html {
padding: 0;
margin: 0;
}
#output {
font-size: 120%;
min-height: 2em;
padding: 0;
margin: 0;
}
.left {
float: left;
}
.right {
float: right;
}
</style>
</head>
<body>
<div id="output" class="left"></div>
</body>
</html>
"""
class Window_Ui:
def setupUi(self, widget):
view = QWebEngineView()
edit = QtWidgets.QLineEdit()
layout = QtWidgets.QVBoxLayout()
layout.addWidget(view)
layout.addWidget(edit)
widget.setLayout(layout)
self.view = view
self.edit = edit
class Window(QtWidgets.QWidget):
def __init__(self, parent = None):
super().__init__(parent)
ui = Window_Ui()
ui.setupUi(self)
self._ui = ui
ui.view.setHtml(html)
page = ui.view.page()
page.loadFinished.connect(self.onLoadFinished)
ui.edit.setText("{-b \pm \sqrt{b^2-4ac} \over 2a}")
ui.edit.textChanged.connect(self.onTextChanged)
self._ready = False
def onLoadFinished(self):
if self._ready:
return
self._ready = True
self.onTextChanged(self._ui.edit.text())
def onTextChanged(self, text):
ui = self._ui
text = text.replace("\","\\")
page = ui.view.page()
page.runJavaScript('convert("{}");'.format(text))
def sizeHint(self):
return QtCore.QSize(300,150)
if __name__ == "__main__":
app = QtWidgets.QApplication([])
window = Window()
window.show()
app.exec()
对于一个学校项目,我们应该制作一个简单的计算器。该项目的目标是教授 github、团队合作、测试、文档和所有爵士乐。这与计算器无关。然而,我和我的团队决定更进一步,我们想创建一个实时显示数学表达式的计算器。
我设法找到了一种方法:使用 PyQt5 及其 QWebEngineView,我能够显示一个简单的网页,并且,使用 javascript,我能够使用 MathJax 实时显示一个方程。但是,也有一些问题:
输入任何数字后,首先,显示屏下方会出现一个状态栏(瞬间),如下所示:
但这还不是全部 - 在最终数字出现之前,首先会显示原始乳胶代码几分之一秒,然后是分数的 HTMLPreview 版本,只有在所有这些之后才会显示最终渲染.
这是 python x javascript 部分:
from PyQt5.QtWidgets import *
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtGui import QFont
import sys
import time
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWebEngineWidgets import QWebEngineView
class Ui_s_cals(object):
def __init__(self):
self.content=["10","+","10"]
def setupUi(self, s_cals):
s_cals.setObjectName("s_cals")
s_cals.resize(300, 500)
s_cals.setWindowTitle("Calculator")
self.display = QWebEngineView(s_cals)
self.display.setGeometry(QtCore.QRect(20, 10, 300, 60))
self.pushButton_n0 = QtWidgets.QPushButton(s_cals)
self.pushButton_n0.setGeometry(QtCore.QRect(80, 400, 61, 61))
self.pushButton_n0.setObjectName("pushButton_n0")
self.pushButton_n0.setText("0")
self.pushButton_n0.clicked.connect(lambda:self.print("0"))
def print(self,number):
self.content.append(number)
print(self.content)
#self.output1.setText(''.join(self.content))
temp=''.join(self.content)
self.expression=temp
self.pageSource = '''
<html><head>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script></script><script>MathJax.Hub.Config({{
jax: ["input/TeX","output/HTML-CSS"],
displayAlign: "left"
}});</script>
</head>
<body>
<p><mathjax style="font-size:1em">$${expression}$$</mathjax></p>
</body></html>
'''.format(expression=self.expression)
self.display.setHtml(self.pageSource)
class Main(QMainWindow):
def __init__(self):
super().__init__()
self.ui = Ui_s_cals()
self.ui.setupUi(self)
self.show()
def main():
calc = QApplication(sys.argv)
instance = Main()
sys.exit(calc.exec_())
if __name__ == '__main__':
start = time.time()
main()
print(time.time() - start)
我花了好几个小时寻找答案。我尝试将 body 的可见性设置为隐藏,然后在 mathjax 完成渲染后通过脚本使其可见,但它没有用。
我尝试了关于堆栈溢出的所有答案,但是 none 的答案指望我在 python 脚本中使用它,这可能是问题所在。如果您知道实时显示方程式的不同方式。
您不需要更改整个页面内容来呈现新的表达式,而是可以使用 QWebEnginePage.runJavaScript
方法。看看input-tex2chtml.html example in MathJax-demos-web
演示:
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWebEngineWidgets import QWebEngineView
html = """
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width">
<title>MathJax v3 with interactive TeX input and HTML output</title>
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js"></script>
<script>
function convert(input) {
output = document.getElementById('output');
output.innerHTML = '';
MathJax.texReset();
var options = MathJax.getMetricsFor(output);
options.display = true;
MathJax.tex2chtmlPromise(input, options).then(function (node) {
output.appendChild(node);
MathJax.startup.document.clear();
MathJax.startup.document.updateDocument();
}).catch(function (err) {
output.appendChild(document.createTextNode(err.message));
});
}
</script>
<style>
body, html {
padding: 0;
margin: 0;
}
#output {
font-size: 120%;
min-height: 2em;
padding: 0;
margin: 0;
}
.left {
float: left;
}
.right {
float: right;
}
</style>
</head>
<body>
<div id="output" class="left"></div>
</body>
</html>
"""
class Window_Ui:
def setupUi(self, widget):
view = QWebEngineView()
edit = QtWidgets.QLineEdit()
layout = QtWidgets.QVBoxLayout()
layout.addWidget(view)
layout.addWidget(edit)
widget.setLayout(layout)
self.view = view
self.edit = edit
class Window(QtWidgets.QWidget):
def __init__(self, parent = None):
super().__init__(parent)
ui = Window_Ui()
ui.setupUi(self)
self._ui = ui
ui.view.setHtml(html)
page = ui.view.page()
page.loadFinished.connect(self.onLoadFinished)
ui.edit.setText("{-b \pm \sqrt{b^2-4ac} \over 2a}")
ui.edit.textChanged.connect(self.onTextChanged)
self._ready = False
def onLoadFinished(self):
if self._ready:
return
self._ready = True
self.onTextChanged(self._ui.edit.text())
def onTextChanged(self, text):
ui = self._ui
text = text.replace("\","\\")
page = ui.view.page()
page.runJavaScript('convert("{}");'.format(text))
def sizeHint(self):
return QtCore.QSize(300,150)
if __name__ == "__main__":
app = QtWidgets.QApplication([])
window = Window()
window.show()
app.exec()