Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
823 views
in Technique[技术] by (71.8m points)

qt - problem displaying sympy rendered svg in python

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_()
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...