html5軟件下載手機版網(wǎng)頁關鍵詞排名優(yōu)化
引入
在代碼里面寫中文就很low,運行時多語言切換是客戶端程序都應該具備的。
qt國際化其實就是qt中字符串的字符集編碼的設置。當然這個設置不是簡單的選擇一下什么語言就好,這個需要編程人員來處理的。
通常對于非拉丁字符(主要指??latin1???字符集)的字符串,就需要使用到??unicode???字符集,而通常使用??UTF-8???編碼。如果只是本地使用一下,直接使用??""??包含文件就可以了。但是有時候設計到網(wǎng)絡傳輸?shù)惹闆r,就要考慮這些了。
QT提供了??QTextCodec??類來進行文本字符集的轉(zhuǎn)換操作。
本文的重點不在于此。深入學習可以看
? QTextCodec && 字符編碼??
? ?Qt 編碼問題QTextCodec??
本文的重點在于QT界面顯示的中文化。
1、控制需要翻譯的文本
在編寫QT程序的時候,對于要翻譯的文本,應當使用??tr()??包含起來。
我們先來看看??tr??函數(shù)的原型,注意,這是一個靜態(tài)函數(shù)。
QString QObject::tr(const char * sourceText, const char * disambiguation = 0, int n = -1)
因為Qt中的類都繼承自??QObject???類,所以這里直接使用了??tr???,如果不是在繼承自QT的類中使用,應該用??Object::tr(…)??來調(diào)用。
這還不是很準確,在宏定義??Q_OBJECT???展開后,會創(chuàng)建一個??QMetaObject???對象,即??static const QMetaObject staticMetaObject;??這個可以看看源碼
對于Q_OBJECT的解析可以看Qt信號與槽機制的基石-MOC詳解
#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???,而這里面定義了一個內(nèi)聯(lián)的??tr???函數(shù)??梢钥闯鲞@里實際是使用了一個靜態(tài)對象??staticMetaObject???的成員函數(shù)??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是經(jīng)過多級函數(shù)調(diào)用才實現(xiàn)了翻譯操作,是有代價的,所以不該用的時候最好不要用。
QLable *label = new QLable(tr("hello"),this);
這次還是以一個??hello world??為例。
先看hello.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>class Widget : public QWidget
{Q_OBJECTpublic: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)
{//創(chuàng)建一個PushButtonQPushButton * 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更新翻譯
在上面,源文件中的相關字符串已經(jīng)使用??tr???函數(shù)包裝起來了。現(xiàn)在要做的就是更新這些要翻譯的字符串到??ts???文件。
??lupdate???就是用于掃描??pro???文件中指定的代碼或UI文件中被??tr??包裝起來的文本的工具
lupdate的使用
??lupdate??的使用可以使用??lupdate --help??來查看。
粗略的說一下這個工具的用法:
使用方法:
lupdate [選項] [項目文件]…
lupdate [選項] [源文件 | 路徑 | @ lst 文件]…-ts ts 文件 | @ lst 文件
(lst文件是一個文本文件,保存一些文件名稱,一行一個)
常用選項 | 說明 |
---|---|
-ts … | 指定輸出文件。 |
-codecfortr | 指定為 tr() 調(diào)用假設的編解碼器。只有與-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 [_] | 指定新文件翻譯的語言。如果未指定,則猜測系統(tǒng)語言。 |
@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
現(xiàn)在我們添加一句
TRANSLATIONS = zh_hans.ts
添加之后使用??lupdate???來生成??zh_hans.ts??文件
o@o-pc:~/hello$ lupdate hello.pro
3. linguits翻譯文本
生成了??ts???文件后就要進行翻譯了。??ts???文件實際上是類似于??xml??文件的,我們可以直接打開它來翻譯。
- 直接翻譯
打開ts文件,我們只需要在????和????之間填寫我們翻譯后的文件即可。
例如我們將?"click me"?翻譯為點擊我。則修改為:
<message><location filename="widget.cpp" line="9"/><source>click me</source><translation type="unfinished">點擊我</translation>
</message>
如果你認為翻譯合格了,沒有問題了,可以將??translation type=“unfinished”>???中的??type="unfinished"??刪除。
- 使用linguits工具翻譯
1、點擊菜單欄 文件 --> 打開 彈出文件選擇對話框后選擇生成的ts文件
2、設置源語言和目標語言,然而并沒什么用
1、選擇要翻譯的短語
2、填寫翻譯的文本
3、翻譯完成后記得保存
4. lrelease發(fā)布翻譯
所謂發(fā)布翻譯,就是使用??lrelease??工具將??ts??文件轉(zhuǎn)換輸出不包含多余信息的??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 | 如果消息有沒有真正的翻譯,使用源文本和 |
5. 在程序中使用翻譯文件
在QT程序中要使用翻譯文件,需要使用到類??QTranslation????,F(xiàn)在來修改??main.cpp??.
#include "widget.h"
#include <QApplication>
#include <QTranslator>int main(int argc, char *argv[])
{QApplication a(argc, argv);QTranslator tsor; //創(chuàng)建翻譯器tsor.load("zh_hans.qm"); //加載語言包a.installTranslator(&tsor); //安裝翻譯器Widget w;w.show();return a.exec();
}
參考
- QT國際化(lupdate/linguits/lrelease)