2

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

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

非常感谢和最良好的祝愿, Geddes

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

2 回答 2

3

您应该能够使用 更改字体setFontFamily

关于您的代码:我还没有真正使用过 PyQt(只有一些 hack,比如 qbzr 中的字体系列......),所以我不能告诉你是否一切都好。但以下不是一个好主意:

    except:
        if text=='': self.browser.clear()
  1. 永远不要用except:. 这也将捕获BaseExceptions like SystemExit,除非您有理由这样做,否则不应捕获它。始终捕获特定异常,或者如果您处于最高级别(在执行未处理的异常处理程序之前)并且想要记录错误,而不是使用except Exception:仅处理基于Exception.
  2. if text==''- 我认为if not text更“pythonic”。
于 2010-11-03T20:37:54.600 回答
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()

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

编辑 这是对方程进行归一化的东西,它看起来像你正在尝试做的,它适用于小写 az 和实数:

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+,后跟一个左括号或单个字母 az [\(]|[a-z]。它使用括号来捕获模式的数字部分和模式的可变部分,并在它们之间插入一个 *。\1*\2.

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

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

于 2010-11-03T20:37:31.700 回答