1. coding
重點1. 必須設定編碼使用utf-8(配合與此QT範例程式所搭配的翻譯檔(.qm檔)也是使用utf-8)
main.cpp
#include <QtGui/QApplication> #include "langswitch.h" #include int main(int argc, char *argv[]) { QApplication a(argc, argv); LangSwitch w; QTextCodec *codec = QTextCodec::codecForName("utf-8"); QTextCodec::setCodecForLocale(codec); QTextCodec::setCodecForCStrings(codec); QTextCodec::setCodecForTr(codec); w.show(); return a.exec(); }
重點2. 翻譯檔的名稱要加入於.pro檔中
我的程式加入三個翻譯檔, 分別是英文, 法文和中文
(最後要放入版子中的翻譯檔其實是.qm檔, 而這邊要加入的是.ts檔, 最後會再使用這些.ts檔去產生.qm檔)
TRANSLATIONS = lang_en.ts \ lang_la.ts \ lang_zh.ts
重點3. 動態切換語系之函式(其他函式如建構子等因與此多國語系的議題關係不大, 故皆省略)
void LangSwitch::changeTr(const QString& qmFilename) { //由於不同的語言可能會有支持或不支持的字型, //所以將三種語言去對應他們分別可使用的字型 //並在切換語系時去做設定 if(qmFilename == "lang_zh") { // 由於helvetica沒有中文, 我上網找到了以中文為主的文泉譯字型 // 並且大小設為12pt, 並設為粗體 QFont font("wenquanyi",12,QFont::Bold); QApplication::setFont(font,"QLabel"); } else if(qmFilename== "lang_en") { QFont font1("helvetica"); QApplication::setFont(font1,"QLabel"); } else if(qmFilename== "lang_la") { QFont font2("helvetica",12,QFont::Bold, true); QApplication::setFont(font2,"QLabel"); } // maybe can be marked.. only for repaint QApplication::processEvents(); repaint(0,0,240,320); static QTranslator* translator; if (translator != NULL) { qApp->removeTranslator(translator); delete translator; translator = NULL; } translator = new QTranslator; if (translator->load(QString("/")+qmFilename)) //load翻譯檔並不需要加上.qm { qApp->installTranslator(translator); ui->retranslateUi(this); //加入此行, 介面(ui_LangSwitch.h檔)才會重新翻譯 } else { qDebug()<<"load "<<qmFilename<<" failed!"; } }
必須要說明的是上面被我highlight起來的第70行等的那三行
QApplication::setFont(font1,"QLabel");
我的目標是將整個介面所顯示的文字都設為可動態轉換語言
所以原本目標是想找到QT有沒有任何一個函式可提供設定整個QT 的字型
但卻發現怎麼查, 試出來都只有部分的元件字型有被設成功
無法一次設定整個QT的字型
(p.s. 其實是可以在執行的時候 帶入 -font
例如 #/LangSwitch -font helvetica -qws &
這樣整個QT的默認字型就都會是helvetica
可是無法動態切換.. )
但我也不可能把介面中所有的元件全部都一個一個 setFont 啊..
最後我找到了以下
void QApplication::setFont ( const QFont & font, const char * className = 0 ) [static]
這個函式
但是..如所見, 此函式代入的第二個參數必須指定某一個物件, 而也只有被指定的物件才會被設定
不過因為我這個QT程式中, 只有QLabel 去做文字顯示
所以只需要針對QLabel 設一次就好
所以如果還要加上其他兩三個想要文字顯示又可翻譯的物件(例如QPushButton等), 那兩三個物件就必須分別去設
例如
QApplication::setFont(font1,"QPushButton");
如果看到此篇文章的人有更好的解法, 請分享一下~XD
重點4. 要翻譯的字串需要加上tr
helloWorld_label->setText(tr("Hello World"));
上面這行, 加(執行)在 重點3 動態切換語系之函式執行之後, 如此一來此QLabel 元件即會照已切換的語系去重新翻譯了
p.s.
上面的 helloWorld_label 這個元件我是在標頭檔加入成員QLabel * helloWorld_label; , 並且在實作檔new出來的
這個元件並不是在.ui檔裡面給拖曳畫出來的喔
若不是在實作檔new出來的元件, 而是在ui檔中拖曳畫出來的元件
而且要翻譯的原文(source)就是ui檔元件的預設文字(text())的話
只需要(重點3)動態切換語系之函式第99行
if (translator->load(QString("/")+qmFilename)) //load檔名不需要加上.qm { qApp->installTranslator(translator); ui->retranslateUi(this); //加入此行, 介面(ui_LangSwitch.h檔)才會重新翻譯 }
ui檔元件的文字就會自動切換了, 並不需要寫 setText(tr())
(下面會有更清楚的解釋)
p.s.注意元件要為可翻譯的屬性
2. 編譯LangSwitch (#make clean;make)
3. 翻譯檔
#lupdate -verbose LangSwitch.pro
即會在相同目錄下, 產生三個.ts檔 (這是最終需要的翻譯.qm檔的來源檔)
不知道為啥, 我下完指令後, 雖然會產生出ts檔
但會出現以下訊息
/usr/include/qt4/QtCore/qbytearray.h:618: circular inclusion of /usr/include/qt4/QtCore/qstring.h
/usr/include/qt4/QtCore/qstringbuilder.h:45: circular inclusion of /usr/include/qt4/QtCore/qstring.h
/usr/include/qt4/QtGui/qwmatrix.h:45: circular inclusion of /usr/include/qt4/QtGui/qmatrix.h
/usr/include/qt4/QtGui/qlayout.h:236: circular inclusion of /usr/include/qt4/QtGui/qboxlayout.h
/usr/include/qt4/QtGui/qgridlayout.h:45: circular inclusion of /usr/include/qt4/QtGui/qlayout.h
不過最後執行起來結果是正常的, 先暫時不管
編輯三個檔案, <translation 刪除未翻譯的提示訊息>加入欲翻譯內容</translation>, 畫面如下
編碼方式需要與QT程式碼中設定的一致 (如右下角的utf-8)
上圖裡的第七行可看出,
只要在實作檔中加上tr() (例如我的
helloWorld_label->setText(tr("Hello World"));
就會在這個ts檔中加入翻譯
而上圖裡的35行可看出,
只要是在.ui檔中的元件(且為可翻譯屬性)
即會加入至此翻譯檔中
這也就是為何先前說. 並不需要另外在實作檔中寫setText(tr())
(除非你想翻譯的原文(source)並不是元件的遇設文字)
接著
#lrelease LangSwitch.pro
在同一個目錄下, 就會產生出翻譯檔了
要在板子上執行的話
除了QT執行檔外, 也必須要放入這三個.qm檔
且放置板子中的路徑, 必須與QT程式中, translator->load() 的路徑相符(我是放根目錄)
另外因為板子裡的font並沒有文泉譯, 所以我必須另外將文泉譯的字型檔案(.qpf或.ttf之類的)
也放進板子中的font的資料夾中
上網看到有論壇說需要設環境變數(font 的路徑)
但我並不需要設定就可以跑了
但我認為有可能是因為在我QT之前, 環境就已經先在別的地方給設好了..
可能還有待確認
----------------------------------------------- 分隔線 ---------------------------------------------------------
參考以下網址:
http://rritw.com/a/bianchengyuyan/C__/20120806/199525.html
http://rritw.com/a/bianchengyuyan/C__/20130916/424516.html
http://mobile.51cto.com/symbian-268453.htm
http://mobile.51cto.com/symbian-272563.htm
http://bbs.csdn.net/topics/390610841
官網解說: http://qt-project.org/doc/qt-4.8/linguist-hellotr.html
以下內容出處為: http://blog.csdn.net/derryzhang/article/details/4872611
多國語界面的實現,在MFC中是很彆扭的。以前在作MFC時,實現多國語言的界面,只有把資源文件做成各個語言的資源DLL,在程序啟動時,根據選擇判斷選擇載入哪個DLL來獲取資源。MFC的資源也是分語言的,在創建資源的時候要選擇,但是這樣的實現還有有弊端。最根本的原因是MFC的資源文件不是Unicode編碼的,而是不同語言的本地碼,至少VC6是這樣的。這樣在中文系統中載入日文的資源,界面出現的是亂碼。
Qt內部採用的全Unicode編碼,這從根本上保證了多國語界面實現的正確性和便捷性。Qt本身提供的linguist工具,就是來實現這個翻譯過程的。實現多國語的步驟大體上說來有這麼幾步:
1、在需要被翻譯的字符串前面標識tr,如QString str=tr(“hello,world!”); ,這很重要,因為翻譯工具會把源碼中tr標識的字符串提取出來,翻譯成其他語言,如果沒有用tr標識的,不會被工具提取。在界面中輸入的文字,默認已經是加上tr的了,所以在翻譯時也能看見。建議:在程序中的字符串使用英文,漢語等通過多國語翻譯來實現,而不要採取把漢字寫在代碼中。
2、在工程文件***.pro中,添加一項TRANSLATIONS += ***.ts ****.ts擴展名為.ts是翻譯的源文件,表示生成這幾個文件。一般我們會在命名中把區域加進去,更好的註釋這些文件是用於什麼語言的,比如中文大多會這樣命名myapp_zh_CN.ts, zh_CN表示的就是中國。
3、使用lupdate工具提取翻譯源文件,命令是這樣的#lupdate ***.pro ,lupdate會解析***.pro即工程文件,生成TRANSLATIONS中的***.ts幾個文件,這些文件可以被 linguist工具打開,按照提示一個一個的翻譯成需要的文件,然後保存就OK,
linguist的使用很簡單,一看界面基本就會了。上面提到的這些工具都是Qt自帶的。
4、使用lrelease工具發布翻譯文件的二進製文件,這樣在程序運行時載入會大大的加快速度。使用方式是#lrelease ***.pro,這個工具會提示你多少語句被翻譯,多少被忽略了等。生成的文件是***.qm,於同名的***.ts只是換了一個擴展名。而這才是我們程序需要使用到的文件。
5、使用***.qm文件。關於這個,我想還是摘抄書上的原文來說明一下:
切換語言分為兩種情況:
1. 程序載入的時候,根據當前的區域設置,自動選擇語言包(.qm),即可;
2. 要求在程序運行過程中動態切換語言,需要
第一種情況,一般在main函數中程序啟動的部分加入如下代碼:
第二種情況,我們假設有一個QComboBox連接了changeLang的槽:
這兩種情況,也可以復合起來用。 |
需要說明的時,一般我們使用設計器來設計界面UI,也就是程序源碼中我們看到的***.ui文件,在載入翻譯器後,我們應該調用ui->retranslateUi() ,這個函數實際上就是把界面控件的text重新載入一遍,可以在ui_***.cpp中看到該函數的實現。
5、在幫助文檔中,關於QTranslator::load有這樣一句話。
The data is not copied. The caller must be able to guarantee that data will not be deleted or modifiled. |
這段話明確的說明了,QTranslator在load以後,並沒有把qm文件中的數據拷貝一份,而是在需要的時候去查詢字符串。如果qm在這期間被刪除或修改,對程序都是有影響的。擴展開來,QTranslator必須保證要一直有效,如果在函數中定義的局部變量,函數結束後就自動釋放掉了,那麼翻譯工作就不能正常進行。所以建議在private中定義個成員變量QTranslator* app_translator;來確保整個翻譯工作的正確性。
留言列表