从PyQt5 QPlainTextEdit获取Unicode字符串

时间:2014-12-26 22:34:36

标签: python unicode utf-8 qt5 pyqt5

我想从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')

1 个答案:

答案 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>