日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

QT tr与Qstring的差别

發布時間:2023/12/10 c/c++ 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 QT tr与Qstring的差别 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在論壇中漂,經常遇到有人遇到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的中文問題

  • QString 采用的unicode,在中文支持上不存在任何問題
  • "我是中文"?這是傳統的?const?char?*?的窄字符串

  • 當將窄字符串賦值到QString時,我們需要告訴它我們的窄串采用的何種編碼(gbk?、utf-8?)
  • 究竟何種編碼主要取決于我們的源代碼文件的編碼(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。

如果你只關心亂碼問題,到此為止就可以了(下面不再關注編碼)。如果想對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中都有比較詳盡的解釋。我們這兒簡單看一下它的這幾個參數:

  • context 上下文,一般就是需要翻譯的字符串所在的類的名字
  • sourceText 需要翻譯的字符串。(我們關注的編碼其實就是它的編碼)
  • disambiguation 消除歧義用的。(比如我們的類內出現兩處"close",一處含義是關閉,另一處含義是親密的。顯然需要讓翻譯人員知道這點區別)
  • encoding 指定編碼。它有兩個值
    • CodecForTr?使用setCodecForTr()設置的編碼來解釋 sourceText

    • UnicodeUTF8 使用utf8編碼來解釋 sourceText
    • 其實這兩個分別對應tr和trUtf8
  • n 處理單復數(對中文來說,不存在這個問題)

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,?constchar?*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??{??returnQCoreApplication::translate(d.stringdata,?s,?c,?QCoreApplication::CodecForTr);??}??/*!?\internal?*/?QString?QMetaObject::trUtf8(const?char?*s,?const?char?*c)?const?{?returnQCoreApplication::translate(d.stringdata,?s,?c,?QCoreApplication::UnicodeUTF8);

}

總結

以上是生活随笔為你收集整理的QT tr与Qstring的差别的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。