Python是否可以在文本框中实时显示LaTex?

时间:2016-04-15 00:12:30

标签: python user-interface tkinter

我计划创建一个GUI,用户可以将其数学表达式输入到文本框中,例如Tkinter Entry Widget,它们的表达式将以您在{{}中键入表达式时所看到的相同方式显示3}}

这可能吗?如果是这样,那么我必须使用哪些模块才能完成此任务?

4 个答案:

答案 0 :(得分:2)

这个问题太宽泛了。我不太确定是否会因此而关闭。尽管如此,这里还有一个关于如何让乳胶以交互方式与Tk和matplotlib一起工作的片段。

在Entry小部件中输入内容,然后按enter键。

gitlab

代码应该生成一个窗口,如下面的一个:

enter image description here

如果你想拥有像他们这样漂亮的界面,这还不够。它们很可能具有类似于Latex到Unicode转换设置的明文。或者甚至可能直接从明文到Unicode,但我不知道任何数学表达式的解析器和乳胶一样好,所以所有规则都可能必须重新编码,这是很多工作所以他们很可能跳过这一步而不是让乳胶完成繁重的工作,然后只需将乳胶解析为Unicode / Utf8或任何编码都可以处理所有符号。

然后他们通过“额外”(即django和jinja模板)抛出一切,根据元素的类型(二元运算符,变量,指数...)为每个元素分配自己的漂亮的css类,以便完整的数学输出,看起来不错,仍然可以复制。

无论如何,在这个问题中有很多事情发生,实际上不可能给出一个简洁的包罗万象的简单答案。

答案 1 :(得分:1)

这是一个工作示例(python2,raspbian),虽然它不是很优雅。这是众多解决方案中的一个解决方案,但它显示了从乳胶源文件到Tkinter程序的所有步骤。

from subprocess import call
import Tkinter

TEX = (  # use raw strings for backslash
  r"\documentclass{article}",
  r"\begin{document}",
  r"$$a^2 + b^2 = c^2$$",
  r"$$x=\frac{-b \pm \sqrt{b^2 - 4ac}}{2a}$$",
  r"\end{document}",
)

with open('doc1.tex','w') as out_file:
  for t in TEX:
    out_file.write("%s\n" % t)

call(['latex','doc1.tex'])
call(['dvips','doc1.dvi','-o','doc1.ps'])
call(['gs','-sDEVICE=ppmraw','-dNOPAUSE','-dBATCH','-dSAFER','-sOutputFile=doc1.ppm','doc1.ps'])

root1 = Tkinter.Tk()
img1 = Tkinter.PhotoImage(file="doc1.ppm")
label1 = Tkinter.Label(root1, image=img1)
label1.pack()
root1.mainloop()

有很多可能的变化:将latex编译为pdf而不是ps;使用其他图像文件格式;使用库PIL来支持其他格式等。

此解决方案非常低效(不要告诉我,我知道)。例如,在我的系统上,ppm文件为1,5Mb。方程式也出现在一个大页面的中间(需要裁剪)。

即使它需要改进,它也会回答你的问题(在Tkinter程序中显示一个LaTeX文档)并且应该给你一个起点。

答案 2 :(得分:1)

还有一种使用sympy的解决方案。部分原因是对this subreddit的回答所启发。特别是,它使用sympy.printing.preview方法。

这是导入部分

#!/usr/bin/python3

from tkinter import *
import sympy as sp
from PIL import Image, ImageTk
from io import BytesIO

然后我定义了GUI,非常标准的东西。我没有付出太多努力

class Root():
    def __init__(self, master):
        #Define the main window and the relevant widgets
        self.master = master
        master.geometry("800x300")
        self.strvar = StringVar()
        self.label = Label(master)
        self.entry = Entry(master, textvariable = self.strvar, width = 80)
        self.button = Button(text = "LaTeX!", command = self.on_latex)
        #The Euler product formula
        self.strvar.set("\prod_{p\,\mathrm{prime}}\\frac1{1-p^{-s}} = \sum_{n=1}^\infty \\frac1{n^s}")

        #Pack everything
        self.entry.pack()
        self.button.pack()
        self.label.pack()

然后我们定义呈现LaTeX(保留缩进)的功能

    def on_latex(self):
        expr = "$\displaystyle " + self.strvar.get() + "$"

        #This creates a ByteIO stream and saves there the output of sympy.preview
        f = BytesIO()
        the_color = "{" + self.master.cget('bg')[1:].upper()+"}"
        sp.preview(expr, euler = False, preamble = r"\documentclass{standalone}"
                   r"\usepackage{pagecolor}"
                   r"\definecolor{graybg}{HTML}" + the_color +
                   r"\pagecolor{graybg}"
                   r"\begin{document}",
                   viewer = "BytesIO", output = "ps", outputbuffer=f)
        f.seek(0)
        #Open the image as if it were a file. This works only for .ps!
        img = Image.open(f)
        #See note at the bottom
        img.load(scale = 10)
        img = img.resize((int(img.size[0]/2),int(img.size[1]/2)),Image.BILINEAR)
        photo = ImageTk.PhotoImage(img)
        self.label.config(image = photo)
        self.label.image = photo
        f.close()

我选择文档类standalone,以使生成的文档的大小适合其内容。然后,我使用包pagecolor使页面与背景无缝融合。另请注意,PIL与每个format不兼容。例如,选择.pdf的输出将在定义img时产生错误,而选择.png则在定义photo时会出现问题。 .ps格式效果很好,它也是矢量格式,很好。

最后一个需求

master = Tk()
root   = Root(master)
master.mainloop()

这是它的样子

Latex


注意: 在那里,我将图片放大了10倍,并缩小了1/2。这仅是因为它看起来更平滑和更好,但这不是必需的。第一次缩放使用.ps格式的矢量性质,因此它不会丢失分辨率,而第二次缩放则对光栅化的图像起作用。

答案 3 :(得分:0)

一些建议:

  • 将Tex转换为后端的pdf / image并改为渲染图像
  • 使用matplotlib
  • 使用Latex进行文本渲染