QT tr與Qstring的差別

2021-09-29 04:26:05 字數 3739 閱讀 6452

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

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

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

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

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

這個問題本多少可說的。因為涉及到的編碼問題和qstring 與中文問題中是完全一樣的,只不過乙個是用的setcodecforcstrings乙個用的是setcodecfortr。

例子:

qstring

s1 = "

我是中文

";qstring

s2("

我是中文

");qstring

s3;s3 = "

我是中文

"

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

qtextcodec::setcodecforcstrings(qtextcodec::codecforname("

gb2312

"));

qtextcodec::setcodecforcstrings(qtextcodec::codecforname("

utf-8

"))

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

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

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。

如果你只關心亂碼問題,到此為止就可以了(下面不再關注編碼)。如果想對tr進一步了解,不妨。。繼續。。

其實,這個才是真正進行翻譯操作的函式,前面我們提到的tr最終是通過呼叫該函式來實現翻譯功能的(稍後我們會看tr是如何呼叫translate的)。

對tr和這個函式,manual中都有比較詳盡的解釋。我們這兒簡單看一下它的這幾個引數:

n 處理單複數(對中文來說,不存在這個問題)

介紹一下tr與translate的關係。前面提到了,tr呼叫的是translate。如果僅僅這樣一說,沒有證據,還真難以讓大家相信。好吧,繼續

你可能說:這不廢話嗎,manual中寫得明白的,它是qobject的靜態成員函式。而且還有原始碼為證:

//來自 src/corelib/kernel/qobject.h

#ifdef qdoc

static

qstring

tr(const

char *sourcetext,const

char *comment = 0, int

n = -1);

static

qstring

trutf8(const

char *sourcetext, const

char *comment = 0, int

n = -1);

#endif

嘿嘿,差點就被騙了,發現沒:它們被預處理語句包住了。

這說明了什麼呢?說明了這段**僅僅是用來生成qt那漂亮的文件的(qdoc3從**中抽取資訊,生成一系列的html格式的manual)。

啊,也就是說,這是假的。那麼真正的定義呢??在乙個大家都很熟悉的地方,猜猜看?

這就是

q_object
該巨集的定義在src/corelib/kernel/qobjectdefs.h中

#

define q_object \

public: \

q_object_check \

static const qmetaobject staticmetaobject; \ 

q_object_getstaticmetaobject \ 

virtual const qmetaobject *metaobject() const; \

virtual void *qt_metacast(const char *); \

qt_tr_functions \

virtual int qt_metacall(qmetaobject::call, int, void **); \

private:

其中的巨集qt_tr_functions

#

define qt_tr_functions \ 

static inline qstring tr(const char *s, const char *c = 0) \

\static inline qstring trutf8(const char *s, const char *c = 0) \

\static inline qstring tr(const char *s, const char *c, int n) \

\static inline qstring trutf8(const char *s, const char *c, int n) \ 

現在看到:tr呼叫的是 staticmetaobject物件的tr函式,staticmetaobject 的定義在moc生成的 ***.moc 或 moc_***.cpp 檔案內(你隨時可以驗證的)。

staticmetaobject 是乙個 qmetaobject 類的例項,我們繼續看一下該類的原始碼:

/*!

\internal

*/  qstring

qmetaobject::tr(const

char *s, const

char *c) const

/*!\internal

*/ qstring

qmetaobject::trutf8(const

char *s, const

char *c) const

{return

QString 與 數字型別的轉換

型別轉換 把qstring轉換為 double型別 方法1.qstring str 123.45 double val str.todouble val 123.45 方法2.很適合科學計數法形式轉換 bool ok double d d qstring 1234.56e 02 todouble o...

QString與char 之間的轉換

qstring與char 之間的轉換 1.qstring轉char 先將qstring轉換為qbytearray,再將qbytearray轉換為char 注意 不能用下面的轉換形式char mm str.tolatin1 data 因為這樣的話,str.tolatin1 得到的qbytearray型...

與QString 有關的轉換 總結

與qstring 有關的轉換 總結 一 qsting 轉 c 基本型別 1 qsting int toint 2 qstring double todouble 3 qstring float tofloat 4 qstring long tolong 5 qstring long long tol...