简介
国际化的英文表述为Internationalization,通常简写为I18N(首尾字母加中间的字符数),一个应用程序的国际化就是使该应用程序可以让其他国家的用户使用的过程。Qt支持现在使用的大多数语言,特别是:
- 所有东亚语言(汉语、日语和朝鲜语)
- 所有西方语言(使用拉丁字母)
- 阿拉伯语
- 西里尔语言(俄语和乌克兰语等)
- 希腊语
- 希伯来语
- 泰语和老挝语
- 所有在Unicode 6.2中不需要特殊处理的脚本
在Qt中,所有的输入部件和文本绘制方式对Qt所支持的所有语言都提供了内置的支持。Qt内置的字体引擎可以在同一时间正确而且精细的绘制不同的文本,这些文本可以包含来自众多不同书写系统的字符。
在Qt中编写代码时要对需要显示的字符串调用tr()函数,完成代码编写后,对这个应用程序的翻译主要包含三步:
1.运行lupdate工具从C++源代码中提取要翻译的文本,这时会生成一个.ts文件,这个文件是XML格式的;
2.在Qt Linguist中打开.ts文件,并完成翻译工作;
3.运行lrelease工具从.ts文件中获得.qm文件,它是一个二进制文件。这里的.ts文件是供翻译人员使用的,而在程序运行时只需要使用.qm文件,这两个文件都是与平台无关的。
第一步,编写源码
介绍这一步的目的是为了提醒在编写源码时,将需要国际化的内容,使用 tr() 函数。
QLabel *label = new QLabel(this);
label->setText(tr("hello Qt!"));
label->move(100,50);
QLabel *label2 = new QLabel(this);
label2->setText(tr("password","mainwindow"));
label2->move(100,80);
QLabel *label3 = new QLabel(this);
int id = 123;
QString name = "yafei";
label3->setText(tr("ID is %1,Name is %2").arg(id).arg(name));
label3->resize(150,12);
label3->move(100,120);
这里向界面上添加了三个标签,因为这三个标签中的内容都是用户可见的,所以需要调用tr()函数。
第二步,更改项目文件
要在项目文件中指定生成的.ts文件,每一种翻译语言对应一个.ts文件。打开myI18N.pro文件,在最后面添加如下一行代码:
TRANSLATIONS = myI18N_zh_CN.ts
这表明后面生成的.ts文件的文件名为“myI18N_zh_CN.ts”,对于.ts的名称可以随意编写,不过一般是以区域代码来结尾,这样可以更好的区分,例如这里使用了“zh_CN”来表示简体中文。最后按下Ctrl+S保存该文件。
第三步,使用lupdate生成.ts文件
当要进行翻译工作时,先要使用lupdate工具来提取源代码中的翻译文本,生成.ts文件。
单击“工具→外部→Qt语言家→更新翻译(lupdate)”菜单项,从概要信息输出栏中可以看到,更新了“myI18N_zh_CN.ts”文件,发现了8个源文本,其中有8条新的翻译和0条已经存在的翻译。这表明可以对程序代码进行更改,然后多次运行lupdate,而只需要翻译新添加的内容。
可以在项目目录中使用写字板打开这个.ts文件,可以看到它是XML格式的,其中记录了字符串的位置和是否已经被翻译等信息。
第四步,使用Qt Linguist完成翻译
这一步一般是翻译人员来做的,就是在Qt Linguist中打开.ts文件,然后对字符串逐个进行翻译。
在系统的开始菜单中启动Linguist,然后点击界面左上角的“打开”图标,在弹出的文件对话框中进入项目目录,打开“myI18N_zh_CN”文件。
1、菜单项和工具栏
2、上下文(Context)窗口
3、字符串(String)窗口
4、短语和表单(Sources and Forms)窗口
如果包含有要翻译字符串的源文件在Qt Linguist中可用,那么这个窗口会显示当前字符串在源文件中的上下文。
5、翻译区域(The Translation Area)
在字符串列表中选择的字符串会出现在翻译区域的最顶端的“Source Text”下面;如果在使用tr()函数时设置了第二个参数消除歧义注释,那么这里还会在“Developer comments”下出现该注释;后面的“translation”中可以输入翻译文本,如果文本中包含空格,会使用“.”显示;最后面的“translator comments”中可以填写翻译注释文本。
6、短语和猜测(Phrases and Guesses)
如果字符串列表中的当前字符串出现在了已经加载的短语参考中,那么当前字符串和它在短语参考中的翻译会被罗列在这个窗口。在这里可以双击翻译文本,这样翻译文本就会复制到翻译区域。
7、警告信息(Warnings)窗口
如果输入的当前字符串的翻译没有通过开启的验证测试,那么在这里会显示失败信息。
第五步,使用lrelease生成.qm文件
可以在Qt Linguist中使用“文件→发布”和“文件→另外发布为”这两个菜单项来生成当前已打开的.ts文件对应的.qm文件,文件会生成在.ts所在目录下。
还可以通过Qt Creator的“工具→外部→Qt语言家→发布翻译(lrelease)”菜单项来完成。
第六步,使用.qm文件
在项目中添加代码使用.qm文件来更改界面的语言。进入main.cpp文件,然后在QApplication a(argc, argv);代码下添加如下代码:
QTranslator translator;
translator.load("../myI18N/myI18N_zh_CN.qm");
a.installTranslator(&translator);
这里先加载了.qm文件(使用了相对路径),然后为QApplication对象安装了翻译。注意,这几行代码一定要放到创建部件的代码之前,比如这里放到了“MainWindow w;”一行代码之前,这样才能对该部件进行翻译。
程序翻译中的相关问题
1、对所有用户可见的文本使用QString
2、对所有文字文本使用tr()函数
3、对加速键的值使用QKeySequence()函数 ,例如:
exitAct = new QAction(tr("E&xit"), this);
exitAct->setShortcuts(QKeySequence::Quit);
4、对动态文本使用QString::arg()函数
实例
描述:通过下拉框选择 中文 / 英文 / 泰文,当前页面与其他页面更换相应语言。
1、当选择中文时
2、当选择英文时
3、当选择泰文时
编码流程
1、对控件上可见文本,在编码时使用 tr() 函数,或者在 界面设计 里直接输入的文本。
typedef enum{
UI_ZH,
UI_EN,
UI_TH
}LANGUAGE;
Q_DECLARE_METATYPE(LANGUAGE)
//初始化 QcomboBox语言下拉框
ui->comboBoxLanguage->addItem(tr("中文"), QVariant::fromValue(UI_ZH));
ui->comboBoxLanguage->addItem(tr("英文"), QVariant::fromValue(UI_EN));
ui->comboBoxLanguage->addItem(tr("泰语"), QVariant::fromValue(UI_TH));
2、给语言下拉框绑定“当前下拉选项下标更改事件”,并在相应的语言下加载对应的 .qm 文件
注意:在加载新的语言时,需要先将已绑定的语言移除。
//语言切换
void SystemSetting::changeLanguage(int index)
{
static QTranslator* translator;
if (translator != NULL)
{
qApp->removeTranslator(translator);
delete translator;
translator = NULL;
}
translator = new QTranslator;
switch (index) {
case 0:
currLanguage = LanguageType::Chinese;
translator->load(":/qm/zh.qm");
qApp->installTranslator(translator);
emit changeLanguage_ZH();
break;
case 1:
currLanguage = LanguageType::English;
translator->load(":/qm/en.qm");
qApp->installTranslator(translator);
emit changeLanguage_EN();
break;
case 2:
currLanguage = LanguageType::Thai;
translator->load(":/qm/th.qm");
qApp->installTranslator(translator);
emit changeLanguage_TH();
break;
default:
break;
}
}
每个语言项下都会发送相对应的切换语言信号,比如英文:emit changeLanguage_EN();
而这些信号绑定了所有页面下的 刷新页面槽方法 refresh_UI()
void AdminMain::changeLanguage_UI()
{
//中文
connect(this->deash->sysSet, SIGNAL(changeLanguage_ZH()), this->deash, SLOT(refresh_UI()));
connect(this->deash->sysSet, SIGNAL(changeLanguage_ZH()), this->deash->sysSet, SLOT(refresh_UI()));
//英文
connect(this->deash->sysSet, SIGNAL(changeLanguage_EN()), this->deash, SLOT(refresh_UI()));
connect(this->deash->sysSet, SIGNAL(changeLanguage_EN()), this->deash->sysSet, SLOT(refresh_UI()));
//泰语
connect(this->deash->sysSet, SIGNAL(changeLanguage_TH()), this->deash, SLOT(refresh_UI()));
connect(this->deash->sysSet, SIGNAL(changeLanguage_TH()), this->deash->sysSet, SLOT(refresh_UI()));
}
3、切换语言后,需要重新刷新界面
void SystemSetting::refresh_UI()
{
ui->language_label->setText(tr(" 系统语言:"));
ui->allChannel__label->setText(tr(" 总通道数:"));
ui->channelType_label->setText(tr(" 滑槽类型:"));
ui->restorationBtn->setText(tr("分期复位"));
ui->configImportBtn->setText(tr("配置导入"));
ui->configExportBtn->setText(tr("配置导出"));
ui->comboBoxLanguage->setItemText(UI_ZH, tr("中文"));
ui->comboBoxLanguage->setItemText(UI_EN, tr("英文"));
ui->comboBoxLanguage->setItemText(UI_TH, tr("泰语"));
ui->comboBoxGrooveType->setItemText(UI_64, tr("64滑槽"));
ui->comboBoxGrooveType->setItemText(UI_80, tr("80滑槽"));
ui->NavbarlineEdit->setText(tr("系统设置"));
ui->SerialNumOk->setText(tr("保存"));
ui->SerialNumLabel->setText(tr("产品序列号"));
}
void setDeashing::refresh_UI()
{
ui->groupBox->setTitle(tr("总控区"));
ui->groupBox_2->setTitle(tr("子控区"));
ui->deashing_label->setText(tr("清灰开关:"));
ui->systemSet_label->setText(tr("系统设置:"));
ui->DeashingTime_label->setText(tr("清灰时间(秒):"));
ui->DeashingPeriod_label->setText(tr("清灰周期(分):"));
ui->NavbarlineEdit->setText(tr("清灰设置"));
}
End!