problem displaying sympy rendered svg in python

|▌冷眼眸甩不掉的悲伤 提交于 2019-11-28 04:41:28

问题


I have the following program which uses sympy and svgmath to render a user's algebraic expression. It nearly works but there are a few issues:

  1. The svg is not actually produced until the program exits so obviously cannot be diplayed.
  2. Is there a way to improve the performance (not looking up 'svgmath.xml' every time etc.)?
  3. Does an actual svg file need to be produced? Can svgmath pass output directly to the QSvgWidget?

Many thanks and best wishes.

from __future__ import division
import sys
import sympy

from PySide.QtGui import *
from PySide.QtCore import *
from PySide.QtXml import *
from PySide.QtSvg import *

from xml import sax
from xml.sax.saxutils import XMLGenerator

from svgmath.tools.saxtools import XMLGenerator, ContentFilter
from svgmath.mathhandler import MathHandler, MathNS

from sympy.printing.mathml import mathml
from sympy.abc import x

from sympy.utilities.mathml import c2p

import libxml2

import StringIO

class Form(QDialog):
    def __init__(self, parent=None):
        super(Form, self).__init__(parent)
        self.browser = QTextBrowser()
        self.browser.setCurrentFont(QFont("Courier New",10,QFont.Bold))
        self.lineedit = QLineEdit("please type an expression")
        self.lineedit.selectAll()
        self.svgwidget = QSvgWidget()
        layout = QVBoxLayout()
        layout.addWidget(self.browser)
        layout.addWidget(self.lineedit)
        layout.addWidget(self.svgwidget)
        self.setLayout(layout)
        self.lineedit.setFocus()
        self.connect(self.lineedit, SIGNAL("textChanged (const QString&)"),self.updateUi)

    def updateUi(self):
        text = unicode(self.lineedit.text())
        for z in range(0,9):
            text = text.replace('x'+str(z),'x^'+str(z))
            text = text.replace(')'+str(z),')^'+str(z))
            text = text.replace(str(z)+'x',str(z)+'*x')
            text = text.replace(str(z)+'(',str(z)+'*(')

        try:
            prettytext = sympy.printing.pretty(sympy.sympify(text))
            self.browser.clear()
            self.browser.append(prettytext)

            # Open all files
            output = open("test.svg", "w")
            config = open("svgmath.xml", "r")

            # Create the converter as a content handler. 
            saxoutput = XMLGenerator(output, 'utf-8')
            handler = MathHandler(saxoutput, config)

            # Parse input file with a namespace-aware SAX parser
            parser = sax.make_parser()
            parser.setFeature(sax.handler.feature_namespaces, 1)
            parser.setContentHandler(handler)
            parser.parse(StringIO.StringIO(c2p(mathml(sympy.sympify(text)), simple=True)))
            self.svgwidget.load("test.svg")

        except Exception:
            if text=='': self.browser.clear()

    app = QApplication(sys.argv)
form = Form()
form.show()
app.exec_()

回答1:


You should close the file handles, because otherwise the data written may not yet have been flushed to the filesystem.

parser.parse()
output.close()

Alternatively, use a with expression.

with open("test.svg", "w") as output:
    ...
    parser.parse()
load()

Does an actual svg file need to be produced?

I think QSvgWidget offers a load slot, which takes a byte string with the file contents.



来源:https://stackoverflow.com/questions/5265226/problem-displaying-sympy-rendered-svg-in-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!