QT tr()函數詳解

用tr的有兩類人:

(1)因爲發現中文老出問題,然後搜索,發現很多人用tr,於是他也開始用tr

(2)另一類人,確實是出於國際化的需要,將需要在界面上顯示的文件都用tr包起來,這有分兩種:

(2a) 用tr包住英文(最最推薦的用法,源碼英文,然後提供英文到其他語言的翻譯包)

(2b) 用tr包住中文(源碼用中文,然後提供中文到其他語言的翻譯包) 


注意,如果你正在用tr包裹中文字符,卻不屬於(2b),那麼,這是個信號:

  • 你在誤用tr
  • 你需要的是QString,而不是tr

如果你確實屬於(2b),請做好心理準備,你可能還會遇到很多困難,請考慮Qt國際化(源碼含中文時)的點滴分析


tr 是做什麼的?下面二者的區別是什麼?

QString text1 = QObject::tr("hello");
QString text2 = QString("hello");

tr是用來實現國際化,如果你爲這個程序提供了中文翻譯包(其中hello被翻譯成中文"你好"),那麼text1的內容將是中文"你好";如果你爲程序提供且使用日文翻譯包,那麼text1的內容將是日文。

tr是經過多級函數調用才實現了翻譯操作,是有代價的,所以不該用的時候最好不要用。

關注的對象:

本文關注的是tr或translate中包含中文字符串的情況:

  • QObject::tr()

  • QCoreApplication::translate()

  • QTextCodec::setCodecForTr

這個問題本多少可說的。因爲涉及到的編碼問題和QString 與中文問題中是完全一樣的,只不過一個是用的setCodecForCStrings一個用的是setCodecForTr。


簡單回顧QString的中文問題:

1) QString 採用的unicode,在中文支持上不存在任何問題

2) "我是中文" 這是傳統的 const char * 的窄字符串

3) 當將窄字符串賦值到QString時,我們需要告訴它我們的窄串採用的何種編碼(gbk?、utf-8?)

4) 究竟何種編碼主要取決於我們的源代碼文件的編碼(windows上一般是gbk,其他平臺一般utf-8)

例子:

QString s1 = "我是中文";
QString s2("我是中文");
QString s3;
s3 = "我是中文"
  • s1、s2 用的是QString的構造函數QString ( const char * str )

  • s3 用的是QString的賦值操作符 QString & operator= ( const char * str)

如果不指定編碼,s1,s2,s3將全部都是(國內大多數人所稱的)亂碼。因爲QString將這些const char *按照latin1來解釋的,而不是用戶期待的gbk或utf8。

QTextCodec::setCodecForCStrings(QTextCodec::codecForName("GB2312"));
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"))

這兩條語句中的一條可以解決問題,至於如何選擇,此處不再重複。


QObject::tr()

說實話,在tr中使用中文不是個好主意。不過既然總有人用(無論是(1)還是(2b)),而且總有人遇到問題,所以還是簡單整理一下吧。

相比QCoreApplication::translate,大家用tr應該用的很多了,儘管不少人不清楚tr究竟是做什麼的^_^


tr("我是中文");

這調用的是下面這個函數(至少我們可這麼認爲是)。

QString QObject::tr ( const char * sourceText, const char * disambiguation = 0, int n = -1 )

與QString("我是中文")完全一樣,你必須告訴tr這個窄字符串是何種編碼?你不告訴它,它就用latin1。於是所謂的亂碼問題就出來了。

如何告訴tr你寫的這幾個漢字在磁盤中保存的是何種編碼呢?這正是

QTextCodec::setCodecForTr(QTextCodec::codecForName("GB2312")); 
QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));

所做的。這兩個選擇的原則,由於和前文完全一樣,此處也不再重複。

如果你的編碼採用的utf8,可以直接使用trUtf8而不必設置setCodecForTr。

如果你只關心亂碼問題,到此爲止就可以了。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章