在C++ GUI Qt4一书中,动态语言切换也就是Qt的国际化是属于Qt的高级部分,今天就来让高级的部分简单化。
为了打造更牛×的程序,界面只有中文肯定是不行的,最起码要有英文。为此Qt提供了一种可以动态切换语言的方式。
在介绍程序前先定义几个概念,Qt的QTranslator 通过加载qm文件实现翻译的效果, 而qm文件是Qt的Linguist工具通过Qt 的lupdate工具生成的ts文件得到的。然后ts文件是通过在pro文件中添加TRANSLATIONS得来的。
知道了qm 、ts 等文件的关系之后,就是在程序中对要翻译的字段的处理。在Qt中,需要对要翻译的字段做tr()处理。Ok,这些规则确定后,接下来通过一组程序把这些规则串起来,主要讲解一些关键的地方,整个工程可以微信公众号后台留下邮箱来获取。先放两张结果图片:
程序平台:ubuntu 14.04、 Qt Creator 3.5.1、Qt 5.5.1
1. UI程序介绍
①语言选项切换UI
使用UI编辑器自动生成的界面
setLanguageDialog::setLanguageDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::setLanguageDialog)
{
ui->setupUi(this);
m_translator = new QTranslator(qApp);
}
void setLanguageDialog::changeEvent(QEvent *event)
{
if(0 != event)
{
switch(event->type())
{
// this event is send if a translator is loaded
case QEvent::LanguageChange:
{
ui->retranslateUi(this);
break;
}
default:
{
break;
}
}
}
QWidget::changeEvent(event);
}
void setLanguageDialog::on_rbn_chinese_clicked()
{
bool ret = m_translator->load(QString(":/Translations/Translations/zh_CN_widget.qm"));
qDebug() << "load qm file ret:" << ret;
qApp->installTranslator(m_translator);
}
void setLanguageDialog::on_rbn_english_clicked()
{
m_translator->load(QString(":/Translations/Translations/en_GB_widget.qm"));
qApp->installTranslator(m_translator);
}
这是一个单例UI,两个按钮对应两种语言的qm文件,使用m_translator来装载qm文件,使用qApp->installTranslato安装翻译器。这里要说明的是,在调用完installTranslator()函数后,语言并不会切换。但所有基于UI创建的Widget都会接收到语言改变的事件,当我们判断是语言改变的事件后,调用ui->retranslateUi()函数,则整个应用程序的语言都会切换。retranslateUi()该函数的调用有一些注意事项,下面结合程序进行说明。
②主widget介绍
其中含有自己添加的UI内容,自己添加的部分要注意。
translateWidget::translateWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::translateWidget)
{
ui->setupUi(this);
ui->lb_goal->setText(tr("study hard every day"));
}
void translateWidget::changeEvent(QEvent *event)
{
if(0 != event && QEvent::LanguageChange == event->type())
{
ui->retranslateUi(this);
}
// convey parent process
QWidget::changeEvent(event);
ui->lb_goal->setText(QApplication::translate("translateWidget", "study hard every day", 0));
}
void translateWidget::on_pbn_setting_clicked()
{
setLanguageDialog *dlg = setLanguageDialog::getRobotIpDlgInstance();
if(dlg->isVisible())
{
dlg->hide();
}
else
{
dlg->show();
}
}
在主widget的事件函数中,多了一句label的setText。我们知道UI上的文字可以通过setText被改变,如果是编辑器自己生成的UI我们可以通过retranslateUi()来切换语言,但如果是通过setText来改变内容的文字,使用retranslateUi()来切换语言则会显示为空(可以进入retranslateUi()函数中查看一下)。此时通过添加对应的setText来实现语言的显示。在这里我们看到了tr("study hard every day"),这是因为只有使用了tr()封装的文本才会被翻译。
2. ts文件的创建
①在Qt pro文件中加入以下代码:
RESOURCES += \
Resources/translate.qrc \
TRANSLATIONS += \
Resources/Translations/zh_CN_widget.ts \
Resources/Translations/en_GB_widget.ts
为管理ts、qm等文件,创建了资源文件,如果以后有其他资源,如图片资源也可进行统一管理。zh_CN和en_GB是国家代码。
②使用lupdate工具生成ts文件
如图是lupdate工具位置。点击lupdate工具后,会在Qt下方General Messages选项输出栏输出对应信息。成功后会有两个ts文件产生。
lupdate工具位置
3. qm文件的发布
有两种方式可以发布qm文件,一种是使用lupdate工具下方的lrelease工具发布qm文件,另一种是使用Linguist工具的File->Release直接发布qm文件,不过要说明的是,在发布qm文件之前,都要使用Linguist工具打开ts文件进行语言翻译,如图:
语言工具位置如图:
最后一点需要补充的是:如果是在多工程的情况下,使用Linguist工具的File->Release这种方式发布qm文件。因为此时使用lrelease工具发布会有警告,导致无法发布qm文件。警告如下:
lrelease warning: Met no 'TRANSLATIONS' entry in project file '***.pro'