天天看點

python string和PyQt的QString的差別

python string和PyQt的QString的差別 以下在Python2.6和PyQt4.4.4 for Python2,6環境下讨論: Python中有兩種有關字元的類型:Python string object和Python Unicode object。主要使用Python string object進行資料輸入輸出。 PyQt中與之相對應的字元有關類

python string和PyQt的QString的差別

以下在Python2.6和PyQt4.4.4 for Python2,6環境下讨論:

Python中有兩種有關字元的類型:Python string object和Python Unicode object。主要使用Python string object進行資料輸入輸出。

PyQt中與之相對應的字元有關類型是:QByteArray和QString。主要使用QString操作資料。

1. Python和PyQt中的類型對應

注意是類型相似,不是相等。

需要先了解編碼:ascii、gb2312、big5,這些是各國自己文字不同的編碼;unicode,國際通用編碼,就是窮盡這個世界上所有的文字,給 每個文字編一個,又分utf-8方案--最常使用的128個英文字母用一個位元組來表示,而中文使用三個位元組來表示,utf-16方案--其中英文和中文都 使用兩個位元組來表示,而其它字元采用四個位元組,utf-32方案--所有的文字都用四個位元組來表示。

unicode就可用來作為各種獨立編碼如ascii、gb2312、big5的轉換中介。

Python中gkb == gb2312。

1)Python string object可以了解為一個接一個位元組(byte,8位)的位元組組,至于表示什麼編碼,與表示文字有關,如:"python string","中文"。注意它是有不同編碼區分的!

PyQt中與之相當的是QByteArray,注意不是QString!

A built-in string object (plain or Unicode) is a sequence of characters used to store and represent text-based information (plain strings are also sometimes used to store and represent arbitrary sequences of binary bytes). (摘自《Python in a NutShell》)

QByteArray can be used to store both raw bytes (including '"0's) and traditional 8-bit '"0'-terminated.(摘自《PyQt手冊》)

2)Python Unicode object可以了解為固定使用utf-16編碼的位元組組,其中英文和中文都使用兩個位元組(16位)來表示,如:u"Python Unicode object"、u"中文"。

PyQt中與之對應的就是QString了。

Unicode string literals have the same syntax as other string literals, with a u or U immediately before the leading quote. (摘自《Python in a NutShell》)

Qt also provides the QString class to store string data. It stores 16-bit Unicode characters, making it easy to store non-ASCII/non-Latin-1 characters in your application.(摘自《PyQt手冊》)

QString stores a string of 16-bit QChars, where each QChar corresponds one Unicode 4.0 character.(摘自《PyQt手冊》)

2. PyQt内部類型轉換

QString有 toAscii()、toUtf8()函數轉換為QByteArray類型,(這個基本不用,因為很少直接用QByteArray類型)有__init__ (self, QByteArray a)函數将QByteArray類型轉為QString。

3. Python string object和Python Unicode object互相轉換

1)Python string object是原始編碼是有區分的,通過 decode('原始編碼') 函數解碼得到通用utf16編碼即Python Unicode object。

>>>"python string".decode('ascii')

或者

>>>"python string".decode()

得到 u"python string"

因為預設按ascii解碼。

>>>"中文".decode('gbk')

得到 u""u4e2d"u6587" ,列印出來就是 中文 二字。(注意結果是2位元組一組,共兩組,對應兩個漢字)

又:"python string".decode('gkb') ,即按漢字來解碼,也可以得到 u"python string",因為gbk編碼也支援英文字母;

但是"中文".decode('ascii') 即按ascii解碼是錯誤的,因為ascii編碼不支援漢字!

>>> "dfdf".decode()

u'dfdf'

>>> "dfdf".decode("ascii")

u'dfdf'

>>> "dfdf".decode("gbk")

u'dfdf'

>>> "中文".decode("gbk")

u'"u4e2d"u6587'

>>>print "中文".decode("gbk")

中文

>>> "中文".decode("gb2312")

u'"u4e2d"u6587'

>>> "中文".decode("ascii")

Traceback (most recent call last):

File "<interactive input>", line 1, in <module>

UnicodeDecodeError: 'ascii' codec can't decode byte 0xd6 in position 0: ordinal not in range(128)

2)Python Unicode object原始編碼固定是utf16,通過 encode('目的編碼') 編碼來得到Python string object。

>>>u"unicode string".encode()

或者

>>>u"unicode string".encode('ascii')

得到

'unicode string',預設目的編碼為ascii。

>>>u"中文".encode("gbk")

得到'"xd4"xd0"xce"xc4',列印出來就是 中文。(注意結果是1位元組一組,共4組)

>>> u"sdff".encode()

'sdff'

>>> u"sdff".encode('ascii')

'sdff'

>>> u"sdff".encode('gbk')

'sdff'

>>> u"sdff".encode('gb2312')

'sdff'

>>> u"中文".encode('gbk')

'"xd6"xd0"xce"xc4'

>>> print u"中文".encode('gbk')

中文

>>> u"中文".encode('ascii')

Traceback (most recent call last):

File "<stdin>", line 1, in <module>

UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordin

al not in range(128)

注意:執行>>> u"中文".encode('gbk')指令需要你的IDE支援gbk編碼,在官方shell下執行肯定沒問題,但如果你的IDE比如PyWin中文輸入異常,則可能報錯。

4. Python string object和Python Unicode object向QString的轉換。

Qt一般不直接操作QByteArray,隻需關注Python string object和Python Unicode object向QString的轉換。

很多關于PyQt4的英文書籍說:PyQt函數需要QString參數的地方都可以直接用Python string object或者Python Unicode object,如果非要轉換可以直接用QtCore.QString()構造。比如《GUI Programming with PyQt》,再如《PyQt手冊》:

Whenever PyQt expects a QString as a function argument, a Python string object or a Python Unicode object can be provided instead, and PyQt will do the necessary conversion automatically.

You may also manually convert Python string and Unicode objects to QString instances by using the QString constructor as demonstrated in the following code fragment:

qs1 = QtCore.QString("Converted Python string object")

qs2 = QtCore.QString(u"Converted Python Unicode object")

但可惜這隻适用于英文即ascii編碼,對于中文則行不通!

直接的QString:

>>> QtCore.QString('中文')

PyQt4.QtCore.QString(u'"xd6"xd0"xce"xc4')

>>> print QtCore.QString('中文')

Traceback (most recent call last):

File "<stdin>", line 1, in <module>

UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-3: ordin

al not in range(128)

>>>

>>> QtCore.QString(u'中文')

PyQt4.QtCore.QString(u'"u4e2d"u6587')

>>> print QtCore.QString(u'中文')

Traceback (most recent call last):

File "<stdin>", line 1, in <module>

UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordin

al not in range(128)

>>>

因為它們都是預設按ascii編碼轉換!

GUI程式設計:

可以建立一個QTextEdit對象myTextEdit, 檢驗:

myTextEdit.append("中文")

或者

myTextEdit.append(u"中文")

或者

myTextEdit.append(QtCore.QString('中文'))

或者

myTextEdit.append(QtCore.QString(u'中文'))

你會發現顯示都是亂碼...因為它們都是預設按ascii編碼進行内部轉換得到QString相應utf16編碼的。

解決方法是:

利用unicode()函數顯示指定gb2312編碼進行中文編碼轉換,轉換後的Python Unicode object則是可以直接作為QString參數代入用的:

>>> unicode('中文', 'gb2312', 'ignore')

u'"u4e2d"u6587'

>>> print unicode('中文', 'gb2312', 'ignore')

中文

>>>

myTextEdit.append(unicode('中文', 'gb2312', 'ignore'))

#用以替代myTextEdit.append(u"中文")

或者多此一舉下:

myTextEdit.append(QtCore.QString(unicode('中文', 'gb2312', 'ignore')))

#用以替代myTextEdit.append(QtCore.QString(u'中文'))

5. QString向Python string object和Python Unicode object的轉換。

Python中需要用Python string object和Python Unicode object的地方可就不一定可以直接用QString了!!!

QString向Python string object轉換可以了解,因為編碼不同。

QString向Python Unicode object的轉換?需要轉換嗎?不都是utf16編碼嗎?

QString是tuf16編碼,但是它的實作并非Python Unicode object那樣直接的utf16碼,而實際是一個QChar串,每個QChar才對應unicode符,是以地位相當但并不相同。

許多英文書籍寫到:可以使用str()函數直接将QString轉換為Python string object,可以使用unicode()直接将QString轉換為Python Unicode object。如《PyQt手冊》:

In order to convert a QString to a Python string object use the Python str() builtin. Applying str() to a null QString and an empty QString both result in an empty Python string object.

In order to convert a QString to a Python Unicode object use the Python unicode() builtin. Applying unicode() to a null QString and an empty QString both result in an empty Python Unicode object.

但同樣隻适用于英文,具體見下面分别分析。

1)QString向Python Unicode object的轉換。

>>> from PyQt4 import QtGui, QtCore

>>> unicode(QtCore.QString('def'))

u'def'

>>> print unicode(QtCore.QString('def'))

def

對于中文,unicode()必須要指定編碼後有效。(這樣也隻針對直接的QString有效?對于Qt GUI程式設計中,從QWidget取得的QString無效?)

>>> from PyQt4 import QtGui, QtCore

>>> unicode(QtCore.QString('中文'))

u'"xd6"xd0"xce"xc4'

>>> print unicode(QtCore.QString('中文'))

Traceback (most recent call last):

File "<stdin>", line 1, in <module>

UnicodeEncodeError: 'gbk' codec can't encode character u'"xd6' in position 0: il

legal multibyte sequence

指定原始編碼後:

>>> unicode(QtCore.QString('中文'),'gbk','ignore')

u'"u4e2d"u6587'

>>> print unicode(QtCore.QString('中文'),'gbk','ignore')

中文 TEST