我想从PyQt5 PlainTextEdit读取和写入unicode字符。
它有一个非常奇怪的问题,经过一些尝试后才会曝光,它是以下内容:
如果我输入字符串:
yóuxiāngdìzhǐ
进入PlainTextEdit并使用该方法(通过单击按钮):
userInput = self.rightTextEdit.toPlainText()
它给了我字符串:
yóuxingdìzhÐ
这显然搞砸了。但是,如果我只将第一个ó
更改为o
,它就不会再出现问题了:
input: youxiāngdìzhǐ
after method call: youxiāngdìzhǐ
所以我猜Qt5在幕后尝试了一些魔法并且它无法猜测编码(为什么它会尝试猜测,最好不要求开发人员选择编码?)。也许它只准备了一些角色,或者它认为ó
是一个非常不寻常的角色,编码需要完全改变。
由于Qt5不再具有任何QString方法,我怎么告诉PlainTextEdit,我希望将整个事物解释为unicode String?
我读到了这个问题:Set Qt default encoding to 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)
此测试使用的变换方法与我在PyQt5 GUI中连接按钮单击的函数中使用的方法相同,并且运行时没有失败。这意味着错误必须在GUI中,我从PlainTextEdit获取String。
当我进入python控制台时:
>>> a = "yóuxiāngdìzhǐ".encode(encoding="utf-8")
>>> a
b'y\xc3\xb3uxi\xc4\x81ngd\xc3\xaczh\xc7\x90'
>>> 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ǐ
PlainTextEdit中的。这导致:
False
(!)所以看起来似乎在PlainTextEdit中对字符串的Qt5解释中存在错误。我该怎么办呢?
编辑3: Python版本:3.4 PyQt5版本:5.2.1 使用的区域设置:(' en_US',' UTF-8')
答案 0 :(得分:2)
<强>更新强>:
您的问题很可能是由于您使用的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'y\xc3\xb3uxi\xc4\x81ngd\xc3\xaczh\xc7\x90'
s.encode('utf-8')
b'y\xc3\xb3uxi\xc4\x81ngd\xc3\xaczh\xc7\x90'
>>> w.toPlainText().encode('utf-8') == s.encode('utf-8')
True
当您尝试打印文本时,可能会出现唯一的实际问题:
>>> print(s)
yóuxiāngdìzhǐ
这为我提供了预期的输出,因为stdout编码符合我的控制台编码,而且我的控制台的字体也包含所有必需的字符。但是如果你的程序试图打印到没有正确配置的控制台(或者只是不能很好地处理unicode),那么你很可能会看到这种或那种的输出错误。 / p>