QT國際化 一 (lupdate/linguits/lrelease)

本文的重點在於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 or -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、設置源語言和目標語言,然而並沒什麼用,(__) language_set.png

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

##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();
}

 

編譯後運行看看。把

zh_hans.qm拷貝到項目工作目錄

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章