Qt中translate、tr关系 与中文问题
| 題外話:何時使用 tr ? 在論壇中漂,經常遇到有人遇到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的中文問題
例子: 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"))這兩條語句中的一條可以解決問題,至于如何選擇,此處不再重復。 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。 如果你只關心亂碼問題,到此為止就可以了(下面不再關注編碼)。如果想對tr進一步了解,不妨。。繼續。。 QCoreApplication::translate我們知道tr是用于實現程序的國際化(或者說多語言翻譯),看Qt相關資料的話,我們知道實現該功能的還有下面這個函數: QString QCoreApplication::translate ( const char * context, const char * sourceText, const char * disambiguation, Encoding encoding, int n )其實,這個才是真正進行翻譯操作的函數,前面我們提到的tr最終是通過調用該函數來實現翻譯功能的(稍后我們會看tr是如何調用translate的)。 對tr和這個函數,manual中都有比較詳盡的解釋。我們這兒簡單看一下它的這幾個參數:
tr與translate這兩個函數的說明,一個在QObject的manual,另一個在QCoreApplication的manual中。 介紹一下tr與translate的關系。前面提到了,tr調用的是translate。如果僅僅這樣一說,沒有證據,還真難以讓大家相信。好吧,繼續 tr 在何處定義你可能說:這不廢話嗎,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) \{ return staticMetaObject.tr(s, c); } \static inline QString trUtf8(const char *s, const char *c = 0) \{ return staticMetaObject.trUtf8(s, c); } \static inline QString tr(const char *s, const char *c, int n) \{ return staticMetaObject.tr(s, c, n); } \static inline QString trUtf8(const char *s, const char *c, int n) \ ?{ return staticMetaObject.trUtf8(s, c, n); }現在看到:tr調用的是 staticMetaObject對象的tr函數,staticMetaObject 的定義在moc生成的 xxx.moc 或 moc_xxx.cpp 文件內(你隨時可以驗證的)。 staticMetaObject 是一個 QMetaObject 類的實例,我們繼續看一下該類的源碼: /*!\internal */QString QMetaObject::tr(const char *s, const char *c) const{return QCoreApplication::translate(d.stringdata, s, c, QCoreApplication::CodecForTr); ?} ?/*! ?\internal */ QString QMetaObject::trUtf8(const char *s, const char *c) const { return QCoreApplication::translate(d.stringdata, s, c, QCoreApplication::UnicodeUTF8); }至此,我們應該都看清楚了。我們的 Q_OBJECT 宏展開后為生成 tr ,tr調用QCoreApplication的translate函數。而該函數需要指定編碼。 |
總結
以上是生活随笔為你收集整理的Qt中translate、tr关系 与中文问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: OLED面板的iPad有戏:三星正为其建
- 下一篇: Linux 下编译并安装配置 Qt