试图在pyqt浏览器中生成等宽输出

时间:2010-11-03 20:18:22

标签: python pyqt sympy

我修改了一小段pyqt代码,以生成用户表达式的实时渲染。我已经使用了sympy的漂亮打印功能,但输出没有正确显示,因为QTextBrowser使用比例而不是等宽字体。

作为初学者,我也欢迎您对代码有任何其他想法。

非常感谢和祝福, 格迪斯

from __future__ import division
import sys
import sympy
from PyQt4.QtCore import *
from PyQt4.QtGui import *

class Form(QDialog):
    def __init__(self, parent=None):
        super(Form, self).__init__(parent)
        self.browser = QTextBrowser()
        self.lineedit = QLineEdit("please type an expression")
        self.lineedit.selectAll()
        layout = QVBoxLayout()
        layout.addWidget(self.browser)
        layout.addWidget(self.lineedit)
        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:
            self.browser.append(sympy.printing.pretty(sympy.sympify(text)))
            self.browser.clear()
            self.browser.append(sympy.printing.pretty(sympy.sympify(text)))
        except:
            if text=='': self.browser.clear()

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

2 个答案:

答案 0 :(得分:3)

您应该可以使用setFontFamily更改字体。

关于你的代码:我还没有真正使用PyQt(只有一些像qbzr中的字体系列那样的黑客......),所以我不能告诉你一切是否正常。但以下不是一个好主意:

    except:
        if text=='': self.browser.clear()
  1. 永远不要使用except:捕获所有例外情况。这也会像SystemExit一样捕获BaseException,除非你有理由这样做,否则不应该抓住它。始终捕获特定的异常,或者如果您处于最高级别(在执行未处理的异常处理程序之前)并且想要记录错误,请使用except Exception:,它仅处理基于Exception的异常。< / LI>
  2. if text=='' - 我认为if not text更像是“pythonic”。

答案 1 :(得分:1)

QTextBrowser继承QTextEdit,因此您可以使用setCurrentFont(QFont)方法设置等宽字体。

self.browser = QTextBrowser()
self.browser.setCurrentFont(QFont("Courier New")) #Or whatever monospace font family you want...

至于关于样式的一般评论,可能有一种方法可以将updateUi()中的文本替换内容更改为正则表达式,但我不能确定没有看到样本数据来弄清楚你要做什么

另外,你应该重构

try:
    self.browser.append(sympy.printing.pretty(sympy.sympify(text)))
    self.browser.clear()
    self.browser.append(sympy.printing.pretty(sympy.sympify(text)))
except:
    if text=='': self.browser.clear()

更像是:

self.browser.clear()
try:
    self.browser.append(sympy.printing.pretty(sympy.sympify(text)))
except:
    if text=='': self.browser.clear()

除了可能捕捉到您期望的实际异常外。

修改 这里的等式正常化它看起来像你想要做的,它适用于小写的a-z和实数:

def updateUi(self):
    text = unicode(self.lineedit.text())
    text = re.sub(r'(\d+)([\(]|[a-z])',r'\1*\2',text) #for multiplication
    text = re.sub(r'([a-z]|[\)])(\d+)',r'\1^\2',text) #for exponentiation

第一个模式查找一个或多个数字\d+,后跟一个左括号或单个字母a-z [\(]|[a-z]。它使用括号来捕获模式的数字部分和模式的可变部分,并在它们之间插入*。 \1*\2

第二个模式查找变量a-z或右括号[a-z]|[\)],后跟一个或多个数字\d+。它使用分组括号再次捕获数字和变量,并在它们之间插入^ \1^\2

它不是很完美(不处理xy --> x*y)但它更接近。如果你想建立一个完整的计算机代数系统,你可能需要建立一个专用的解析器:)