QT國際化(lupdate/linguits/lrelease)
本文由烏合之眾瞎寫http://www.cnblogs.com/oloroso/
qt國際化其實就是qt中顯示文本語言的設置。
QT提供了QTextCodec類來進行文本字符集的轉換操作。
本文的重點不在於此。深入學習可以看
本文的重點在於QT界面顯示的中文化。
1、控制需要翻譯的文本
在編寫QT程序的時候,對於要翻譯的文本,應當使用tr()包含起來。
我們先來看看tr函數的原型,注意,這是一個靜態函數。
QString QObject::tr(const char * sourceText, const char * disambiguation = 0, int n = -1)
因為Qt中的類都繼承自QObject類,所以這里直接使用了tr,如果不是在繼承自QT的類中使用,應該用Object::tr(...)來調用。
這還不是很准確,在宏定義Q_OBJECT展開后,會創建一個QMetaObject對象,即static const QMetaObject staticMetaObject;這個可以看看
#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,而這里面定義了一個內聯的tr函數。可以看出這里實際是使用了一個靜態對象staticMetaObject的成員函數tr。
# 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); }
例如對於一個QLabel控件,將其顯示的文本使用tr括起來。tr是經過多級函數調用才實現了翻譯操作,是有代價的,所以不該用的時候最好不要用。
QLable *label = new QLable(tr("hello"),this);
這次還是以一個hello world為例。
先看hello.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = 0);
~Widget();
public slots:
void btn_click();
};
#endif // WIDGET_H
再看hello.cpp
#include "widget.h"
#include <QPushButton>
#include <QMessageBox>
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
//創建一個PushButton
QPushButton * btn = new QPushButton(tr("click me"),this);
//連接信號和槽
connect(btn,SIGNAL(clicked()),this,SLOT(btn_click()));
}
Widget::~Widget()
{
}
void Widget::btn_click()
{
QMessageBox::information(NULL, tr("click button"),
tr("hello world"), QMessageBox::Yes);
}
2、lupdate更新翻譯
在上面,源文件中的相關字符串已經使用tr函數包裝起來了。現在要做的就是更新這些要翻譯的字符串到ts文件。lupdate就是用於掃描pro文件中指定的代碼或UI文件中被tr包裝起來的文本。
lupdate的使用
lupdate的使用可以使用lupdate --help來查看。
粗略的說一下這個工具的用法:
使用方法:
lupdate [選項] [項目文件]...
lupdate [選項] [源文件 | 路徑 | @ lst 文件]...-ts ts 文件 | @ lst 文件
(lst文件是一個文本文件,保存一些文件名稱,一行一個)
| 常用選項 | 說明 |
|---|---|
| -ts
|
指定輸出文件。 |
| -codecfortr
|
指定為 tr() 調用假設的編解碼器。只有與-ts 有效。 |
| -extensions
|
擴展支持的文件后綴。擴展名列表必須用逗號分隔。默認值: 'java,jui,ui,c,c++,cc,cpp,cxx,ch,h,h++,hh,hpp,hxx,js,qs,qml'。 |
| -no-recursive | 指定不遞歸掃描的目錄 |
| -recursive | 遞歸掃描指定目錄 |
| -I
|
附加的包含文件目錄 |
| -no-ui-lines | 對ui文件的掃描不保留行號 |
| -pro
|
.Pro 文件的名稱。對於具有.pro 文件語法,但不同的文件后綴的文件非常有用。 |
| -source-language
|
指定新文件的源字符串的語言。默認值Posix 標准。 |
| -target-language
|
指定新文件翻譯的語言。如果未指定,則猜測系統語言。 |
| @lst-file | 從 lst 文件讀取附加文件的名稱 (每行一個)。 |
生成ts文件
1、在命令行中指定方式生成
這里只生成一個翻譯文件zh_hans.ts,其實可以跟多個文件名來生成多個用於翻譯的ts文件。這個方式會忽略掉pro文件中指定要生成的翻譯文件。
o@o-pc:~/hello$ lupdate hello.pro -ts zh_hans.ts
Updating 'zh_hans.ts'...
Found 3 source text(s) (3 new and 0 already existing)
2、在pro文件中指定
這里我們先修改一個hello.pro文件。
這是原本的hello.pro文件:
QT += core gui
TARGET = hello
TEMPLATE = app
SOURCES += main.cpp\
hello.cpp
HEADERS += hello.h
LIBS += -lxcb
現在我們添加一句
TRANSLATIONS = zh_hans.ts
添加之后使用lupdate來生成zh_hans.ts文件
o@o-pc:~/hello$ lupdate hello.pro
3、linguits翻譯文本
生成了ts文件后就要進行翻譯了。ts文件實際上是類似於xml文件的,我們可以直接打開它來翻譯。
1、直接翻譯
先打開看看

我們只需要在<translation>和</translation>之間填寫我們翻譯后的文件即可。
例如我們將"click me"翻譯為"點擊我^_^"。則修改為:
6 <message>
7 <location filename="widget.cpp" line="9"/>
8 <source>click me</source>
9 <translation type="unfinished">點擊我</translation>
10 </message>
如果你認為翻譯合格了,沒有問題了,可以將translation type="unfinished">中的type="unfinished"刪除。
2、使用linguits工具翻譯
1、點擊菜單欄 文件 --> 打開 彈出文件選擇對話框后選擇生成的ts文件
2、設置源語言和目標語言,然而並沒什么用,(^__^)

1、選擇要翻譯的短語
2、填寫翻譯的文本
3、翻譯完成后記得保存

4、lrelease發布翻譯
所謂發布翻譯,就是使用lrelease工具將ts文件轉換輸出不包含多余信息的qm文件(qm文件是二進制文件,非文本文件)。
我們先來看看翻譯后的ts文件。
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="zh_CN">
<context>
<name>Widget</name>
<message>
<location filename="widget.cpp" line="9"/>
<source>click me</source>
<translation>點擊我^_^</translation>
</message>
<message>
<location filename="widget.cpp" line="20"/>
<source>click button</source>
<translation>單擊按鈕</translation>
</message>
<message>
<location filename="widget.cpp" line="21"/>
<source>hello world</source>
<translation>你好 世界</translation>
</message>
</context>
</TS>
使用lrelease生成qm文件
o@o-pc:~/hello$ lrelease zh_hans.ts -qm zh_hans.qm
lrelease使用簡要說明
使用方法:
lrelease [選項] 項目文件
lrelease [選項] ts 文件 [-qm qm 文件]
| 選項 | 說明 |
|---|---|
| -idbased | 使用 Id 而不是源字符串作為消息的鍵 |
| -compress | QM 文件壓縮 |
| -nounfinished | 不使用未完成的翻譯 |
| -removeidentical | 如果源文本與翻譯后的文本相同,不使用這個 |
| -markuntranslated
|
如果消息有沒有真正的翻譯,使用源文本和
|
4、在程序中使用翻譯文件
在QT程序中要使用翻譯文件,需要使用到類QTranslation。現在來修改main.cpp.
#include "widget.h"
#include <QApplication>
#include <QTranslator>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QTranslator tsor; //創建翻譯器
tsor.load("zh_hans.qm"); //加載語言包
a.installTranslator(&tsor); //安裝翻譯器
Widget w;
w.show();
return a.exec();
}
編譯后運行看看。

