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.注意元件要為可翻譯的屬性

QT translatable check box  

 

 

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>, 畫面如下

edit ts file  

編碼方式需要與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函數中程序啟動的部分加入如下代碼:

 

[cpp] view plaincopy
 
  1. QString locale = QLocale::system().name());     // for example: zh_CN, en_US   
  2. QTranslator *translator =  new  QTranslator(app);    
  3.   
  4. translator->load(QString( "./language/"  + locale));   //會在當前目錄下的language目錄下尋找,可以不帶".qm"後綴名  
  5.   
  6. app->installTranslator( translator );                   //安裝翻譯器  
  

 

第二種情況,我們假設有一個QComboBox連接了changeLang的槽:

 

[cpp] view plaincopy
 
  1. connect(langCombo, SIGNAL(currentIndexChanged( int )),  this , SLOT(changeLang( int )) );  
  2.   
  3. // 載入不同的語言包  
  4.   
  5. void  WizarDialog::changeLang(  int  langIndex )  
  6.   
  7. {  
  8.   
  9.   QTranslator *translator =  new  QTranslator(qApp);  
  10.   
  11.   switch ( langCombo->currentIndex() ){  
  12.   
  13.   case  0:  
  14.   
  15.     translator->load(QString( "./language/pt_BR" ));  
  16.   
  17.     break ;  
  18.   
  19.   case  1:  
  20.   
  21.     translator->load(QString( "./language/en_US" ));  
  22.   
  23.     break ;  
  24.   
  25.   case  2:  
  26.   
  27.     translator->load(QString( "./language/zh_CN" ));  
  28.   
  29.   default :  
  30.   
  31.     break ;  
  32.   
  33.   }  
  34.   
  35.   qApp->installTranslator( translator );  
  36.   
  37.   this ->initGUI();  
  38.   
  39. }  
  40.   
  41.    
  42.   
  43. // initGUI() 中會有大量的tr函數  
  44.   
  45. void  WizarDialog::initGUI()  
  46.   
  47. {  
  48.   
  49.   this ->setWindowTitle(tr( "RTA04W" ));  
  50.   
  51.   /* ...... */  
  52.   
  53. }  
  

 

這兩種情況,也可以復合起來用。

 

需要說明的時,一般我們使用設計器來設計界面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;來確保整個翻譯工作的正確性。

arrow
arrow
    文章標籤
    QT Linux
    全站熱搜
    創作者介紹
    創作者 lynn770707 的頭像
    lynn770707

    雜記

    lynn770707 發表在 痞客邦 留言(0) 人氣()