我想从 PyQt5 PlainTextEdit 读取和写入 unicode 字符。
它有一个非常奇怪的问题,经过一番尝试才发现,如下所示:
如果我输入字符串:
yóuxiāngdìzhǐ
进入纯文本编辑并使用该方法(通过单击按钮):
userInput = self.rightTextEdit.toPlainText()
它给了我字符串:
yóuxingdìzhÐ
这显然是搞砸了。但是,如果我只将第一个ó
更改为o
它突然不再有问题:
input: youxiāngdìzhǐ
after method call: youxiāngdìzhǐ
所以我想 Qt5 在幕后尝试了一些魔法,但它无法猜测编码(为什么它无论如何都要尝试猜测,要求开发人员选择编码不是更好吗?也许它只准备了一些字符,或者它认为ó
是一个如此不寻常的字符,需要完全更改编码。
由于Qt5不再有任何QString方法,我应该如何告诉PlainTextEdit,我希望将整个事情解释为Unicode String?
我读到这个问题:将Qt默认编码设置为UTF-8,但标记为解决问题的答案只能解决Qt4,而Qt5不再有方法。
以下是我的源代码的重要部分:
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
...
class PinyinTransformerMainWindow(QMainWindow):
def createControls(self):
...
self.rightTextEdit = QPlainTextEdit('', self)
self.rightTransformButton = QPushButton('Transform (numbers)')
...
def addControlsEventHandlers(self):
self.leftTransformButton.clicked.connect(self.transformToPinyinWithTones)
self.rightTransformButton.clicked.connect(self.transformToPinyinWithNumbers)
def transformToPinyinWithNumbers(self):
userInput = self.rightTextEdit.toPlainText()
print("User input right:", userInput)
...
编辑#1:
我写了这样的测试:
tonedText = "yóuxiāngdìzhǐ"
numberedText = "you2xiang1di4zhi3"
self.assertEquals(self.pinyin_tones_2_numbers_transformer.transform(tonedText), numberedText)
此测试使用转换方法,该方法与我在函数 o 中使用的方法相同,在 PyQt5 GUI 中连接按钮单击并且运行不会失败。这意味着错误必须在GUI中,我从PlainTextEdit中获取字符串。
当我进入 python 控制台时:
>>> a = "yóuxiāngdìzhǐ".encode(encoding="utf-8")
>>> a
b'yxc3xb3uxixc4x81ngdxc3xaczhxc7x90'
>>> a.decode()
'yóuxiāngdìzhǐ'
>>> a.decode(encoding="utf-8")
'yóuxiāngdìzhǐ'
所以这不是python3的问题。但是,如果我在代码中执行此操作:
self.leftTextEdit.toPlainText().encode('utf-8').decode('utf-8')
我得到错误的字符串:
yóuxingdìzhÐ
编辑#2:
我现在添加了另一个像这样的 print():
print("Condition:", self.leftTextEdit.toPlainText().encode('utf-8').decode('utf-8') == "yóuxiāngdìzhǐ")
然后输入
yóuxiāngdìzhǐ
在纯文本编辑中。这导致:
False
(!因此,在PlainTextEdit中对字符串的Qt5解释中确实存在错误。我能做些什么呢?
编辑3:蟒蛇版本:3.4PyQt5 版本:5.2.1使用的区域设置:("en_US"、"UTF-8")
更新:
您的问题很可能是由于您使用的 PyQt5 版本中的错误造成的。至少升级到 PyQt-5.3.2 很可能会修复它。
Qt没有问题,它可以正确处理所有内容。
您可以在交互式会话中轻松验证这一点:
>>> from PyQt5 import QtWidgets
>>> app = QtWidgets.QApplication([''])
>>> w = QtWidgets.QPlainTextEdit()
>>> s = 'yóuxiāngdìzhǐ'
>>> w.setPlainText(s)
>>> w.toPlainText().encode('utf-8')
b'yxc3xb3uxixc4x81ngdxc3xaczhxc7x90'
s.encode('utf-8')
b'yxc3xb3uxixc4x81ngdxc3xaczhxc7x90'
>>> w.toPlainText().encode('utf-8') == s.encode('utf-8')
True
当您尝试打印文本时,可能会出现唯一真正的问题:
>>> print(s)
yóuxiāngdìzhǐ
这为我提供了预期的输出,因为 stdout 编码与我的控制台的编码匹配,并且我的控制台的字体包含所有必要的字符。但是,如果您的程序尝试打印到尚未正确配置的控制台(或者无法很好地处理 unicode),那么您很可能会看到一种或另一种损坏的输出。