1. 步骤描述
- 将代码中的字符串使用tr()进行包裹,以便Qt提取字符串用于生成翻译资源文件
- 在项目文件中指定需要导出的翻译文件(.ts文件)
TRANSLATIONS = english.ts chinese.ts
,使用lupdate
工具 - 使用
Linguist
程序打开.ts
文件,将字符串翻译为目标语言 - 使用
lrelease
工具将翻译好的翻译文件,发布为.qm
文件,可以直接在Linguist
工具中点击发布 - 在程序中通过
QTranslator
加载不同的.qm
文件,实现不同语言的切换
2. tr() 函数使用
用tr()包装过的字符串,可以被Qt自动提取到翻译文件中。
2.1 tr()
函数调用
- 在使用了
Q_OBJECT
宏定义的类或QObject
的子类中,都可以直接使用,否则需要使用QObject::tr()调用 - 或在类定义中用
Q_DECLARE_TR_FUNCTIONS
宏把tr()
函数添加到类中,之后就可以直接调用了
2.2 tr()
函数的注意事项
- 尽量使用常量字符串,不要使用字符串变量,否则将不能被正确提取
char* errorStr = "不能删除记录"; QString str2 = tr(errorStr);
- 若要在tr()函数中使用字符串变量,需要在定义字符串的地方用Qt_TR_NOOP()宏进行标记,这在使用字符串数组时比较有用
- tr()不能使用拼接的动态的字符串,正确用法如下:
tr("第%1行").arg(current.row());
- 为了避免在程序中遗漏对某个字符串进行tr()包装,可以在配置文件中添加
DEFINES+=Qt_NO_CAST_FROM_ASCII
,来避免这种错误,
这样编译时会禁止const char隐式转换为QString,强制每个字符串必须使用tr()或QLatin1String
QLatin1String是一个关于const char的封装类
3. 示例
界面如下:
项目文件如下:
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++17
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
widget.cpp
HEADERS += \
widget.h
FORMS += \
widget.ui
# important !!!
TRANSLATIONS = english.ts chinese.ts
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
RESOURCES += \
language.qrc
生成翻译文件:工具->外部->Linguist->Update Translations
,此时在项目目录下会生成english.ts
和 chinese.ts
两个文件
翻译翻译文件:打开Linguist
工具,选择chinese.ts
文件,界面如下
翻译对应的字符串,如下所示:
发布翻译好的内容:文件->发布
,在Linguist
工具中操作
将生成的.qm
文件添加的项目的资源文件中
编写加载代码:
#include "widget.h"
#include "ui_widget.h"
extern QApplication* pApp;
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_comboBox_textActivated(const QString &arg1)
{
Q_UNUSED(arg1);
if(ui->comboBox->currentIndex()==0){
translator.load(":/english");
}else if(ui->comboBox->currentIndex()==1){
translator.load(":/chinese");
}else{
translator.load(":/english");
}
qApp->installTranslator(&translator);
}
// 调用installTranslator后,系统会给窗体发送信号将产生了changeEvent槽产生event
void Widget::changeEvent(QEvent* e)
{
QWidget::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
ui->retranslateUi(this);
break;
default:
break;
}
return;
}
ui->retranslateUi(this)
的作用就是刷新界面显示新的语言。
注意:
若窗口是由代码实现的,则需要专门设计一个retranslateUi()
函数,这样做会麻烦,特别是当窗口过多时。所以大部分软件在切换完语言后需要重启生效,因为窗口创建时会自动调用retranslateUi()
函数。
4. 参考
Qt 5.9 C++ 开发指南 16.1 多语言界面