關於qt中的tr()函式

2021-07-07 10:08:51 字數 3838 閱讀 3789

在論壇中漂,經常遇到有人遇到tr相關的問題。用tr的有兩類人:

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

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

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

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

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

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

這個問題本多少可說的。因為涉及到的編碼問題和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是用於實現程式的國際化(或者說多語言翻譯),看qt相關資料的話,我們知道實現該功能的還有下面這個函式:

其實,這個才是真正進行翻譯操作的函式,前面我們提到的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

關於qt中的tr()函式

在論壇中漂,經常遇到有人遇到tr相關的問題。用tr的有兩類人 注意哦,如果你正在用tr包裹中文字元,卻不屬於 2b 那麼,這是個訊號 如果你確實屬於 2b 請做好心理準備,你可能還會遇到很多困難,請考慮qt國際化 原始碼含中文時 的點滴分析 tr 是做什麼的?下面二者的區別是什麼?qstring t...

關於qt中的tr()函式

在論壇中漂,經常遇到有人遇到tr相關的問題。用tr的有兩類人 注意哦,如果你正在用tr包裹中文字元,卻不屬於 2b 那麼,這是個訊號 如果你確實屬於 2b 請做好心理準備,你可能還會遇到很多困難,請考慮 qt國際化 原始碼含中文時 的點滴分析 tr 是做什麼的?下面二者的區別是什麼?qstring ...

關於qt中的tr()函式

在論壇中漂,經常遇到有人遇到tr相關的問題。用tr的有兩類人 注意哦,如果你正在用tr包裹中文字元,卻不屬於 2b 那麼,這是個訊號 如果你確實屬於 2b 請做好心理準備,你可能還會遇到很多困難,請考慮qt國際化 原始碼含中文時 的點滴分析 tr 是做什麼的?下面二者的區別是什麼?qstring t...