2013-06-18 43 views
0

我正在寫一個Qt界面的計算程序,我想在單位寫的區域(即,m^2乳膠輸出,或平方米)。如何在PySide QLabel中編寫指數?

如果我使用的特殊字符²此代碼:area_label = QtGui.QLabel("m²"),它將在GUI中顯示以下內容:m²

我懷疑這可能是一個編碼問題,寫什麼我會尋找平方指數的方式?

附加問題:有沒有辦法輸出任何指數,任何一個沒有定義爲特殊字符(比如m^8)?

附加信息: 我正在使用python 2.7.2,使用PySide 1.1.1版和Qt 4.7.4。在Windows 7 SP1中工作,但我希望我的代碼儘可能跨平臺。

此外,由於我在使用Windows並使用法語口音(如àé),因此我在我的文件開頭使用此編碼行:# -*-coding:Latin-1 -*

+0

如果您希望我們幫忙弄清楚您的編碼問題,您將不得不向我們展示一些示例代碼,並告訴我們您是否使用Python 2.x或3.x。 – abarnert

+0

但是......如果你將mfc編碼爲UTF-8,然後嘗試將結果顯示爲Latin-1,那麼'm-²'就是你所得到的,所以......一種可能性是你編碼爲UTF-8,但你已經爲您的系統默認配置了Qt,這與cp1252類似。 (IIRC,'PySide'可以在任何地方使用已解碼的unicode字符串以及'str' /'bytes'字符串;如果是這樣,簡單的解決方案就是在任何地方都使用unicode。) – abarnert

+0

我更新了我的問題,謝謝提醒! – PhilMacKay

回答

3

你的編碼問題似乎是你傳遞的UTF-8字符串,PySide/Qt試圖根據你的系統編碼來解釋,這是Latin-1兼容的東西(比如cp1252,傳統的Windows默認的西歐語言)而不是UTF-8。你可以很容易地看到這一點:

>>> print u'm\u00b2'.encode('utf-8').decode('latin-1') 
m² 

PySide可以採取unicode串無處不在。所以,如果你只是使用unicode而不是str/bytes,包括在PySide的界面,你應該沒問題。


是有辦法,以輸出任何指數,沒有被定義爲一個特殊字符的任一項(說平方公尺8)?

好,⁸(U + 2078)是定義爲一個特殊字符,由事實證明我是可以在這裏輸入證明。

但是,您必須編寫自己的代碼來解析表達式並生成正確的上標字符。

U + 2070到U + 209F的上標和下標塊包含您需要的所有字符,除了2和3,它們在U + 00B2和U + 00B3的拉丁-1兼容位置。 (某些字體會將U + 2072和U + 2073作爲等效字符顯示,但這些字體不正確,因此您不應該依賴該字體。另外,U + 2071和U + 00B9都顯示爲1,並且某些字體區分他們,你可能想打印出整個列表,看看哪些更適合你。)

把每個數字變成標功能如下:

def superscript(digit): 
    if digit in (2, 3): 
     return unichr(0x00B0 + digit) 
    else: 
     return unichr(0x2070 + digit) 

所以,一個非常簡單的包裝將是:

def term(base, exponent): 
    return base + u''.join(superscript(int(digit)) for digit in exponent) 

現在:

>>> print term('x', '123') 
xⁱ²³ 

但是,如果你想要東西莫靈活的,你可能會想生成HTML而不是純文本。 Qt的最新版本可以直接在QLabel中使用HTML。

如果您可以從您的表達式中生成MathML,Latex等,則可以使用這些格式生成HTML的工具。

但對於一個真正簡單的例子:

def term(base, exponent): 
    return u'{}<sup>{}</sup>'.format(base, exponent) 

當打印出來,這將只顯示x<sup>123</sup>,但被卡住時,在QLabel(或堆棧溢出的答案),顯示爲x 。


我USINT這個編碼線:# -*-coding:Latin-1 -*

爲什麼?如果完全可以使用UTF-8編輯文本文件,那將使您的生活變得更加輕鬆。首先,Latin-1沒有任何上標但是1,2和3的字符,這意味着您將不得不寫入像u'm\2074'而不是僅寫入的內容u'm⁴'

此外,使用它有點誤導一個幾乎但不完全是emacs格式的編碼聲明。無論是使用emacs的格式(與最後連字符和適當的間距):

# -*- coding: Latin-1 -*- 

......還是不要:

# coding=Latin-1 

無論如何,所有的編碼行代碼來告訴Python如何解釋你的字符串文字。如果創建非unicode文字(沒有u前綴),那麼在某個時刻您仍然需要decode。而且,如果你自己沒有這樣做,PySide將不得不猜測,它會猜測你的系統編碼(這可能是cp1252--它足夠接近拉丁文-1的上標,但不夠接近UTF-8 )。

因此,要解決所有的問題,您:

  • 使用UTF-8編碼,如果可能的。
  • 如果您不能使用UTF-8編碼,請使用顯式的Unicode轉義符或動態生成的字符串來處理文字中缺失的字符Latin-1。
  • 製作所有的文字Unicode。
  • 儘可能在代碼中使用Unicode字符串。
  • 如果你確實需要任何地方的字節串,明確地編碼/解碼它們,而不是讓Python/PySide/Qt爲你猜。
+0

感謝您的提示,我能夠找到解決方案。我需要將我的第一行改爲'# - * - coding:UTF-8 - *'以使其接受非ascii字符,並且必須將我的字符串從''spam²'''更改爲'u'spam²「'使其工作。我仍然不知道爲什麼我必須這樣做。 – PhilMacKay

+1

@PhilMacKay:如果您想在迭代中使用任何Unicode字符,則需要編碼聲明,否則Python會將這些文字解釋爲Latin-1。您需要'u'前綴,因爲否則這些文字將被編碼爲UTF-8字節字符串,而不是Unicode字符串 - 並且,正如我所解釋的,如果您將編碼字節字符串傳遞給PySide,它將嘗試使用您的系統編碼對其進行解碼,不是UTF-8。 – abarnert

+0

謝謝,我會接受你的回答,因爲你幫助我瞭解情況並解決問題。 – PhilMacKay