您的编码问题似乎是您正在传递 UTF-8 字符串,PySide/Qt 试图根据您的系统编码来解释它,这是与 Latin-1 兼容的(如 cp1252,西欧语言的传统 Windows 默认值)而不是 UTF-8。你可以很容易地看到这一点:
>>> print u'm\u00b2'.encode('utf-8').decode('latin-1')
m²
PySide 可以在unicode
任何地方使用字符串。所以,如果你只是unicode
在任何地方使用而不是str
/ bytes
,包括在 PySide 的接口上,你应该没问题。
有没有办法输出任何指数,任何未定义为特殊字符的指数(比如 m^8)?
嗯,⁸ (U+2078)被定义为一个特殊字符,我可以在这里输入它就证明了这一点。
但是,您必须编写自己的代码来解析表达式并生成正确的上标字符。
U+2070 到 U+209F 中的上标和下标块包含您需要的所有字符,但 2 和 3 除外,它们在 U+00B2 和 U+00B3 保留在与 Latin-1 兼容的位置。(有些字体会将 U+2072 和 U+2073 显示为等效字符,但这些字体不正确,因此您不应该依赖它。另外,1 同时显示为 U+2071 和 U+00B9,并且有些字体可以区分他们。您可能想打印出整个列表,看看哪些更适合您。)
将每个数字转换为上标的函数如下所示:
def superscript(digit):
if digit in (2, 3):
return unichr(0x00B0 + digit)
else:
return unichr(0x2070 + digit)
所以,一个非常简单的包装器是:
def term(base, exponent):
return base + u''.join(superscript(int(digit)) for digit in exponent)
现在:
>>> print term('x', '123')
xⁱ²³
但是,如果您想要更灵活的东西,您可能会想要生成 HTML 而不是纯文本。Qt 的最新版本可以直接在QLabel
.
如果您可以从表达式生成 MathML、Latex 等,则有一些工具可以从这些格式生成 HTML。
但是对于一个非常简单的例子:
def term(base, exponent):
return u'{}<sup>{}</sup>'.format(base, exponent)
打印出来时,它只会显示x<sup>123</sup>
,但当卡在QLabel
(或堆栈溢出答案)中时,显示为 x 123。
我正在使用这个编码行:# -*-coding:Latin-1 -*
.
为什么?如果您可以使用 UTF-8 编辑文本文件,那您的生活会轻松很多。一方面,Latin-1 除了 1、2 和 3 之外没有任何上标字符,这意味着您将不得不写类似的东西u'm\2074'
而不仅仅是写u'm⁴'
此外,使用几乎但不完全是 emacs 格式的编码声明有点误导。使用 emacs 格式(带有最后的连字符和适当的间距):
# -*- coding: Latin-1 -*-
……或者不:
# coding=Latin-1
无论如何,编码行所做的就是告诉 Python 如何解释您的字符串文字。如果您创建非unicode
文字(没有u
前缀),您仍然需要decode
在某些时候使用它们。而且,如果您自己不进行解码,PySide 将不得不猜测,它会猜测您的系统编码(可能是 cp1252——对于上标而言它与 Latin-1 足够接近,但与 UTF-8 不够接近)。
因此,要解决您的所有问题:
- 如果可能,请使用 UTF-8 编码。
- 如果您不能使用 UTF-8 编码,请使用显式 Unicode 转义或动态生成字符串来处理文字中缺少的字符 Latin-1。
- 将所有文字设为 Unicode。
- 在代码中尽可能使用 Unicode 字符串。
- 如果您确实需要任何地方的字节字符串,请显式编码/解码它们,而不是让 Python/PySide/Qt 为您猜测。