Qt5多国语言国际化及测试实例

Qt提供了一种国际化方案,而不是采用了INI配置文件的方式。Qt中的国际化方法与GNU gettext类似,它提供了tr()函数与gettext()函数对应,而返以后的资源文件则以“.qm”命名,且其国际化的机制与它的元对象系统密切相关。

 

国际化支持的实现

在支持国际化的过程中,通常在Qt中利用QString、QTranslator等类和tr()函数能够很方便地加入国际化支持,具体工作如下:

(1)使用QString对象表示所有用户可见的文本。由于QString内部使用Unicode编码实现,所以它可以用于表示所有需要向用户呈现的文本。当然,对于仅程序员可见的文本并不需要都变为QString对象,可利用Qt提供的QCString或原始的“char *”。

(2)使用tr()函数获取所有需要翻译的文本。在Qt的翻译机制下,QObject::tr()函数可以帮助程序员取得翻译之后的文本。对于从QObject继承而来的类,QObject::tr()函数最终由QMetaObject::tr()实现。在某些时候,如果无法使用QObject::tr()函数,则可以直接调用QCoreApplication::translate()取得翻译之后的字符串。

(3)使用QString::arg()方法组织动态文本。有些时候,一段文本需要由一些静态文本和动态变量组合起来,如常见的情况“printf("The value of i is: %d", i)”。对于这种动态文本的翻译,由于语言习惯的问题,如果简单地采用这种连接字符串的方法,则可能会带来一些问题,如下面的字符串用于表示任务的完成情况:

 QString m = tr("Mission status: " )+ x + tr("of ") + y +tr("are completed");

其中,x和y是动态的变量,三个字符串被x和y分隔开,它们能够被很好地编译,因为“x of y”是英语中分数的表示方法,如4 of 5是分数4/5,在不同的语言中,分子和分母的位置可能是颠倒的,在这种情况下,数字4和5的位置在翻译时无法被正确地放置。由此可见,孤立地翻译被分隔开的字符串是不行的,改进的办法是使用QString:: arg()方法:

QString m = tr("Mission status: %1 of %2 are completed").arg(x).arg(y);

(4)利用QTranslator::load()QCoreApplication::installTranslator()函数读取对应的翻译之后的资源文件。翻译工作者将提供包含翻译之后的字符串的资源文件“*.qm”,程序员还需要做的是定义QTranslator对象,并使用load()函数读取相应的“.qm”文件,利用QCoreApplication:: installTranslator()函数安装QTranslator对象。

翻译工作:“*.qm”文件的生成

对于翻译工作者,主要是利用Qt提供的工具lupdatelinguistlrelease(它们都可以在Qt安装目录的“bin”文件夹下找到)协助翻译工作并生成最后需要的“.qm”文件,它包括以下内容。

(1)利用lupdate工具从源代码中扫描并提取需要翻译的字符串,生成“.ts”文件。类似编译时用到的qmake,运行lupdate时也需要指定一个“.pro”的文件,可以单独创建这个“.pro”文件,也可以利用编译时用到的“.pro”文件,只需定义好变量TRANSLATIONS即可。

(2)利用linguist工具来协助完成翻译工作,即打开前面用lupdate生成的“.ts”文件,对其中的字符串逐条进行翻译并保存。由于“.ts”文件采用了XML格式,所以也可以使用其他编辑器来打开“.ts”文件并翻译。

(3)利用lrelease工具处理翻译好的“.ts”文件,生成格式更为紧凑的“.qm”文件。这便是翻译工作者最终需要提供的资源文件,它所占的空间比“.ts”文件小,但基本不具有可读性,只有QTranslator能够正确地识别它。

多国语言国际化实例1

操作步骤如下。

(1)新建一个GUI工程“TestHello.pro”,在UI界面上添加四个按钮,并分别将文本修改为如图所示。

(2)修改“TestHello.pro”文件,添加如下代码:

 TRANSLATIONS = TestHello.ts

(3)编译。记住,一定要先编译,如果没有编译就进行下面的步骤,则生成的“.ts”文件只是一个仅有标题栏的框架。

(4)编译完成后,打开命令行窗口,进入“TestHello.pro”工程目录,执行命令:      

lupdate TestHello.pro 

在工程下生成一个“.ts”文件,如果没有编译,则提示“Found 1 source text”。若已经编译,则提示“Found 5 source text(s)”,如图所示。

生成的TestHello.ts文件内容:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1">
<context>
    <name>MainWindow</name>
    <message>
        <location filename="mainwindow.ui" line="14"/>
        <source>MainWindow</source>
        <translation type="unfinished"></translation>
    </message>
    <message>
        <location filename="mainwindow.ui" line="27"/>
        <source>hello</source>
        <translation type="unfinished"></translation>
    </message>
    <message>
        <location filename="mainwindow.ui" line="40"/>
        <source>how are you</source>
        <translation type="unfinished"></translation>
    </message>
    <message>
        <location filename="mainwindow.ui" line="53"/>
        <source>I am fine</source>
        <translation type="unfinished"></translation>
    </message>
    <message>
        <location filename="mainwindow.ui" line="66"/>
        <source>and you ?</source>
        <translation type="unfinished"></translation>
    </message>
</context>
</TS>

 (5)运行Qt自带工具linguist(Qt 语言家),在主界面上选择“文件”→“打开”菜单项,选择“TestHello.ts”文件,单击“打开”按钮,根据需要设置源语言和目标语言,此处为默认状态:源语言为任意国家语言,目标语言为China的Chinese,其界面如图所示。

(6)在第二栏中选择要翻译的字符串,在下面两行中输入对应的翻译文字(需要自己输入翻译文字),单击上面的 按钮,如图所示。 当翻译全部完成(这里,“MainWindow”译为“主窗口”;“hello”译为“你好”;等等)后,保存退出。

 被翻译家翻译之后的ts文件:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="zh_CN">
<context>
    <name>MainWindow</name>
    <message>
        <location filename="mainwindow.ui" line="14"/>
        <source>MainWindow</source>
        <translation>主窗口</translation>
    </message>
    <message>
        <location filename="mainwindow.ui" line="27"/>
        <source>hello</source>
        <translation>你好</translation>
    </message>
    <message>
        <location filename="mainwindow.ui" line="40"/>
        <source>how are you</source>
        <translation>你好吗</translation>
    </message>
    <message>
        <location filename="mainwindow.ui" line="53"/>
        <source>I am fine</source>
        <translation>我挺好的</translation>
    </message>
    <message>
        <location filename="mainwindow.ui" line="66"/>
        <source>and you ?</source>
        <translation>你呢?</translation>
    </message>
</context>
</TS>

(7)选择“文件”→“发布”菜单项,或者在命令行中输入“lrelease TestHello.pro”,生成“TestHello.qm”文件,如图所示。

qm文件已经不具备可读性,但是它更为紧凑,只有QTranslator能够正确识别它:

<竏曙湑?縛〗軧   ( n?   ?踫g   0€   _鰠%    ?   礽   ?   bc:Y}v?       	I am fine   
MainWindow   N;z桽?       
MainWindow   
MainWindow   O`Tb       	and you ?   
MainWindow   O`Y}       hello   
MainWindow   O`Y}T       how are you   
MainWindow

 (8)修改源代码

#include "mainwindow.h"

#include <QApplication>
#include<QTranslator>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    //生成翻译家并加载qm文件
    QTranslator *translator = new QTranslator;
    //路径为qm文件在系统中的路径
    translator->load ("D:/QtProject/TestHello/TestHello.qm");
    //安装翻译家
    a.installTranslator (translator);
    MainWindow w;
    w.show();
    return a.exec();
}

运行程序:

 实例2选择语言翻译文字

用一个下拉菜单来选择语言,并且下面有一个需要翻译文字的标签。 操作步骤如下。 (1)在头文件“LangSwitch.h”中定义LangSwitch类,创建用户界面。

操作步骤如下。 (1)在头文件“LangSwitch.h”中定义LangSwitch类,创建用户界面。

#include <QWidget>
#include <QComboBox>
#include <QLabel>
class LangSwitch : public QWidget
{
     Q_OBJECT
public:
     LangSwitch(QWidget *parent = 0);
     ~LangSwitch();
private slots:
     void changeLang(int index);			//(a)
private:
     void createScreen();			//(b)
     void changeTr(const QString& langCode);
     void refreshLabel();
     QComboBox* combo;			//在界面中可以看见的下拉菜单
     QLabel* label;				//在界面中可以看见的标签
};

 (2)源文件“LangSwitch.cpp”中的具体实现代码如下:

#include "langswitch.h"
#include <QVBoxLayout>
#include <QTranslator>
#include <QApplication>
LangSwitch::LangSwitch(QWidget *parent)
     : QWidget(parent)
{
     createScreen();
}
LangSwitch::~LangSwitch()
{
}

 createScreen()函数用于创建基本的界面,其具体实现代码如下:

void LangSwitch::createScreen()
{
    combo = new QComboBox;
    combo->addItem("English", "en");					//(a)
    combo->addItem("Chinese", "zh");
    combo->addItem("Latin", "la");
    label = new QLabel;
    refreshLabel();							//设置标签的内容
    QVBoxLayout* layout = new QVBoxLayout;
    layout->addWidget(combo, 1);
    layout->addWidget(label, 5);
    setLayout(layout);
    connect(combo, SIGNAL(currentIndexChanged(int)),
          this, SLOT(changeLang(int)));					//(b)
}

其中, (a) combo->addItem("English", "en")、combo->addItem("Chinese", "zh")和combo-> addItem("Latin", "la"):将三个语言选项(英文、中文和拉丁文)添加到下拉菜单中,并设置三个选项的值分别为“en”、“zh”和“la”(这是ISO标准中语言的简写形式)。 (b) changeLang(int):改变语言。 refreshLabel()函数的具体实现如下:

void LangSwitch::refreshLabel()
{
      label->setText(tr("Hello World"));		//(a)
}

 changeLang()函数改变语言的具体代码如下:

void LangSwitch::changeLang(int index)
{
      QString langCode = combo->itemData(index).toString();	//(a)
      changeTr(langCode);				//读取相应的“.qm”文件
      refreshLabel();					//刷新标签上的文字
}

其中, (a) QString langCode = combo->itemData(index).toString():从所选的菜单项中取得对应语言的值(“en”、“zh”和“la”)。

changeTr()函数读取对应的“.qm”文件,并调用installTranslator()方法安装QTranslator对象,其具体实现代码如下:

void LangSwitch::changeTr(const QString& langCode)
{
    static QTranslator* translator;					//(a)
    if(translator != NULL)
    {
       	qApp->removeTranslator(translator);
       	delete translator;
       	translator = NULL;
    }
    translator = new QTranslator;
    QString qmFilename = "lang_" + langCode;				//(b)
    if(translator->load(QString("D:/Qt/CH15/CH1502/LangSwitch/")+qmFilename))
    {
        	qApp->installTranslator(translator);
    }
}

 其中, (a) static QTranslator* translator:由于需要动态改变语言,所以如果已经安装了QTranslator对象,则首先需要调用removeTranslator()函数移除原来的QTranslator对象,再安装新的对象。因此,定义了一个static的QTranslator对象以方便移除和重新安装。 (b) QString qmFilename = "lang_" + langCode:将“.qm”文件的路径设定在项目“D:\Qt\ CH15\CH1502\LangSwitch”路径下,分别命名为lang_en.qm、lang_zh.qm和lang_la.qm。

(3)提取需要翻译的字符串并翻译,生成“.qm”文件(这个工作通常由专门的工作组负责),具体操作如下。 ① 修改“langswitch.pro”文件,即在后面加上TRANSLATIONS的定义(加黑部分代码)。修改完的“langswitch.pro”文件的具体内容如下:

TRANSLATIONS = lang_en.ts \
               lang_zh.ts \
               lang_la.ts

 ② 利用lupdate工具提取需要翻译的字符串,执行lupdate命令及结果如图

此时,得到了lang_en.ts、lang_zh.ts和lang_la.ts共三个文件。但是还需要完成如下工作。 

(a)利用linguist工具翻译这几个“.ts”文件。直接利用Qt的linguist工具打开需要翻译的“.ts”文件,就可以进行字符串的翻译,这里三个版本的字符串分别译为“Hello World”(English)、“你好,世界”(Chinese)和“Orbis, te saluto”(Latin),翻译完成后保存退出,如图

 (b)生成各个“.ts”文件相应的“.qm”文件。这个工作可以利用lrelease工具来完成,其用法与lupdate工具相同,只是改用命令“lrelease LangSwitch.pro”,执行lrelease命令如图

上述所有准备工作完成后,便可运行程序,不同版本的界面如图所示。

 通常,一个系统对语言的切换采用广播事件,而不是简单地发送信号的方式处理。

### 如何在Qt应用程序中实现多国语言输入法支持 #### 使用QInputContext类创建自定义输入法上下文 为了使Qt应用程序能够处理多种语言的输入,可以通过继承`QInputContext`来创建自定义的输入法上下文对象。这允许程序根据不同的需求加载特定的语言包并管理其状态[^1]。 ```cpp class MyInputContext : public QInputContext { public: bool filterEvent(const QEvent* event); }; ``` #### 利用资源文件和翻译器(QTranslator) 对于界面文本的本地化工作,则依赖于`.qm`格式的二进制翻译文件以及`QTranslator`组件。开发人员可以在项目的`.pro`文件里指定要编译成QM文件的TS源文件路径,并通过C++代码动态加载这些翻译数据到运行中的应用实例当中去[^3]。 ```cpp #include <QTranslator> #include <QApplication> int main(int argc, char *argv[]) { QApplication app(argc, argv); QTranslator translator; if (translator.load(":/translations/myapp_zh_CN")) { // 加载对应国家/地区的qm文件 app.installTranslator(&translator); // 安装翻译器至应用程序 } MainWindow w; w.show(); return app.exec(); } ``` #### 构建与维护翻译文档(TS文件) 借助Qt Linguist工具可方便地管理和更新不同语种下的字符串映射关系表——即所谓的TS文件。它不仅提供了图形化的编辑环境让用户直观操作,还具备批量导出导入功能以便团队协作时共享进度[^5]。 #### 测试多国语言特性 当完成了上述准备工作之后,还需要利用专门准备好的测试套件验证整个流程是否正常运作。例如,在开源平台上找到的相关项目就包含了完整的示例工程用于展示怎样正确设置一个多语言支持的应用场景[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SOC罗三炮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值