python - 从 PyQt5 QPlainTextEdit 获取 Unicode 字符串

标签 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 字符串?

我读了这个问题: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 中,我在 GUI 中从 PlainTextEdit 获取字符串。

当我进入 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ǐ

在纯文本编辑器中。结果是:

False

(!) 因此,Qt5 对 PlainTextEdit 中字符串的解释似乎确实存在错误。我能做什么呢?

编辑3: Python版本:3.4 PyQt5版本:5.2.1 使用的区域设置:('en_US', 'UTF-8')

最佳答案

更新:

您的问题很可能实际上是由于您使用的 PyQt5 版本中的错误造成的。至少升级到 PyQt-5.3.2 很可能会修复它。


Qt 中没有问题,它可以正确处理一切。

您可以在交互式 session 中轻松地亲自验证这一点:

>>> 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ǐ

这为我提供了预期的输出,因为标准输出编码与我的控制台的编码相匹配,而且我的控制台的字体包含所有必要的字符。但是,如果您的程序尝试打印到尚未正确配置的控制台(或者无法很好地处理 unicode),那么您很可能会看到一种或另一种损坏的输出。

关于python - 从 PyQt5 QPlainTextEdit 获取 Unicode 字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27662653/

相关文章:

python - 将数据从 c++ 程序传递到 linux 上的 python 程序

Python 列出 : join list by index

C++:使用未声明的标识符 'u8'

python - 将可变大小的 numpy 数组转换为 Tensorflow 张量

C# String.Format() 返回错误字符

c++ - C++11 正则表达式是否适用于 UTF-8 字符串?

java - 如何使用 ICU 库转换日语半角/全角字符

python - 类型错误 : 'utf8' is an invalid keyword argument for Compat32 smtplib email error message

c++ - 有没有办法在 C++ 中检测 Windows 和 Linux 上的文件名编码?

c# - Python 是否适合编写标准、兼容且完整的 SOAP Web 服务?