【问题标题】:problem displaying sympy rendered svg in python在 python 中显示 sympy 渲染的 svg 的问题
【发布时间】:2011-07-13 00:31:00
【问题描述】:

我有以下程序,它使用 sympy 和 svgmath 来呈现用户的代数表达式。它几乎可以工作,但存在一些问题:

  1. 直到程序退出后,svg 才会真正生成,因此显然无法显示。
  2. 有没有办法提高性能(不是每次都查找“svgmath.xml”等)?
  3. 是否需要制作实际的 svg 文件? svgmath 可以直接将输出传递给 QSvgWidget 吗?

非常感谢和最良好的祝愿。

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_()

【问题讨论】:

    标签: python qt svg pyside sympy


    【解决方案1】:

    您应该关闭文件句柄,否则写入的数据可能尚未刷新到文件系统。

    parser.parse()
    output.close()
    

    或者,使用with 表达式。

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

    是否需要制作实际的 svg 文件?

    我认为QSvgWidget 提供了一个load 插槽,它采用带有文件内容的字节字符串。

    【讨论】:

    • 再次感谢!我会试一试的。
    • output.close() 命令完美运行 - 谢谢!你认为有办法不必每次都加载'svgmath.xml'吗? (我认为这会提高性能)。另外,你如何让 svgmath 产生一个字节字符串?再次感谢!
    • 我从未使用过 PyQt,但根据文档 (pyside.org/docs/pyside/PySide/QtSvg/QSvgWidget.html),您需要传入一个 QByteArray,这可能会提供一个采用 strbytes 对象。
    • 对于配置文件:我快速浏览了svgmath的源代码。遗憾的是,我没有找到重用配置文件的内置方法。但是,如果您查看mathhandler.py:MathHandler:__init__,修复它并重用MathConfig 实例应该不会太难。
    • 好的,谢谢!我有点超出我的深度(我只是一个不起眼的数学老师),但我非常感谢你在过去几天的帮助。我会研究并考虑您的最新建议。底线 - 我非常高兴能够让它正常工作!
    猜你喜欢
    • 2012-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-05
    • 1970-01-01
    相关资源
    最近更新 更多