Qt 国际化多语言
Qt 的国际化方案非常成熟,核心思路是:代码中用 tr() 包裹文本 → 工具提取生成 .ts 翻译文件 → Qt Linguist 翻译 → 生成 .qm 二进制文件 → 程序加载。
由于项目中需要用到多语言,接下来完整走一遍流程。
第一步:准备项目和代码
1.1 创建 Qt 项目(通常是已有项目)
在 Qt Creator 中新建一个 Qt Widgets Application,假设命名为 MyApp。
1.2 用 tr() 包裹所有需要翻译的文本
cpp
// mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 所有需要翻译的文本都用 tr() 包裹
ui->label->setText(tr("Hello World"));
ui->pushButton->setText(tr("Click Me"));
}
MainWindow::~MainWindow()
{
delete ui;
}
关键规则:
tr()是QObject的静态方法,任何继承自QObject的类都可以直接使用- 非
QObject类中使用QObject::tr() - 字符串字面量必须包裹,不能用变量
cpp
// 正确 ✅
button->setText(tr("Open"));
// 错误 ❌ ------ 不会被翻译
QString text = "Open";
button->setText(text);
第二步:配置项目文件 (.pro)
在 .pro 文件中添加 TRANSLATIONS 变量,指定要生成的翻译文件名:
qmake
# MyApp.pro
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
SOURCES += main.cpp mainwindow.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui
# 添加这一行:指定要生成的翻译文件
TRANSLATIONS += MyApp_zh_CN.ts \
MyApp_ja.ts \
MyApp_ko.ts \
MyApp_ar.ts
这里配置了中文、日文、韩文和阿拉伯四种语言的翻译文件。
命名规范 :应用名_语言代码[_国家代码].ts
zh_CN= 简体中文zh_TW= 繁体中文ja= 日文ko= 韩文en= 英文ar= arabic 阿拉伯语
第三步:生成 .ts 翻译源文件
方法一:Qt Creator 菜单(推荐)
菜单栏选择:工具 → 外部 → Linguist → 更新翻译 (lupdate)
Qt Creator 会自动扫描源代码,生成 .ts 文件。
方法二:命令行
打开终端,进入项目目录,执行:
bash
lupdate MyApp.pro
运行后,项目目录下会生成 MyApp_zh_CN.ts、MyApp_ja.ts、MyApp_ko.ts 文件。
.ts 是 XML 格式的翻译源文件,内容大致如下:
xml
<context>
<name>MainWindow</name>
<message>
<source>Hello World</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Click Me</source>
<translation type="unfinished"></translation>
</message>
</context>
- 如果没有找到Qt Linguist,需要手动添加,例如我单独下载qtcreator19.0.0,但是用的qt是qt5.14.2,此时可以通过下载自带的qtcreator4.11来打开
工具->外部->Qt语言家。我比较想用qtcreator19.0.0,所以我自行添加了工具工具->外部->配置,具体的配置如图


第四步:用 Qt Linguist 翻译
4.1 打开 Qt Linguist
- Windows:开始菜单 → Qt → Qt Linguist
- Linux/Mac:命令行输入
linguist
4.2 翻译流程
- 在 Qt Linguist 中打开
MyApp_zh_CN.ts(文件 → 打开) - 左侧上下文列表 选择要翻译的类(如
MainWindow) - 中间区域选择要翻译的字符串
- 在下方翻译输入框中填写译文
- 按
Ctrl+Enter或点击 ✓ 图标标记为"已翻译"
常用快捷键:
| 操作 | 快捷键 |
|---|---|
| 下一个未翻译 | Ctrl+J |
| 确认翻译 | Ctrl+Enter |
| 复制原文到译文 | Ctrl+B |
4.3 保存并发布
- 保存:
Ctrl+S - 发布(生成 .qm):文件 → 发布
发布后,同目录下会生成 MyApp_zh_CN.qm 文件。
第五步:在代码中加载翻译文件
5.1 基础方案 - 启动时自动加载
cpp
// main.cpp
#include <QApplication>
#include <QTranslator>
#include <QLocale>
#include <QLibraryInfo>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
// 创建翻译器
QTranslator translator;
// 获取系统语言(如 "zh_CN")
QString locale = QLocale::system().name();
// 加载对应的 .qm 文件
// 假设 .qm 文件放在应用程序目录的 translations 文件夹下
if (translator.load(QString(":/translations/MyApp_%1").arg(locale))) {
app.installTranslator(&translator);
}
// 备选:从文件系统加载
// if (translator.load("translations/MyApp_" + locale)) {
// app.installTranslator(&translator);
// }
MainWindow w;
w.show();
return app.exec();
}
5.2 将 .qm 文件打包到资源文件 (推荐)
新建资源文件
右键点击项目根目录 → 添加新文件...
选择:Qt → Qt 资源文件,创建 translations.qrc 资源文件,创建后会自动打开资源编辑器:
点击 添加前缀,输入 /translations 或 /
点击 添加文件,选择你已经生成的 .qm 文件
xml
<!DOCTYPE RCC>
<RCC version="1.0">
<qresource prefix="/translations">
<file>MyApp_zh_CN.qm</file>
<file>MyApp_ja.qm</file>
<file>MyApp_ko.qm</file>
</qresource>
</RCC>
在 .pro 中添加:
qmake
RESOURCES += translations.qrc
然后在代码中用 :/translations/ 前缀访问。
第六步:运行时动态切换语言
cpp
// mainwindow.h
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
void switchLanguage(const QString &locale);
private:
QTranslator *m_translator; // 保存翻译器指针
};
// mainwindow.cpp
void MainWindow::switchLanguage(const QString &locale)
{
// 移除旧的翻译器
if (m_translator) {
qApp->removeTranslator(m_translator);
delete m_translator;
m_translator = nullptr;
}
// 创建并安装新翻译器
m_translator = new QTranslator(this);
if (m_translator->load(QString(":/translations/MyApp_%1").arg(locale))) {
qApp->installTranslator(m_translator);
}
// 关键:刷新界面上的所有文本
retranslateUi();
}
void MainWindow::retranslateUi()
{
// 重新设置所有需要翻译的文本
ui->label->setText(tr("Hello World"));
ui->pushButton->setText(tr("Click Me"));
setWindowTitle(tr("My Application"));
}
// 处理语言切换事件
void MainWindow::changeEvent(QEvent *event)
{
if (event->type() == QEvent::LanguageChange) {
retranslateUi(); // 语言改变时重新翻译
}
QMainWindow::changeEvent(event);
}
语言切换菜单示例
cpp
// 假设有个下拉框
connect(languageComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
[this](int index) {
switch(index) {
case 0: switchLanguage("zh_CN"); break;
case 1: switchLanguage("en"); break;
case 2: switchLanguage("ja"); break;
}
});
第七步:高级技巧
7.1 带参数的翻译
cpp
// 支持复数形式
label->setText(tr("%n file(s) found", "", count));
// 带参数的字符串
label->setText(tr("Hello, %1! Welcome to %2.").arg(name).arg(appName));
7.2 为翻译人员添加上下文注释
cpp
//: This is the label for the username input field
//~ Context: Login dialog
label->setText(tr("Username"));
//:开头的是给翻译人员的注释//~开头的是额外的上下文信息
注释会出现在 Qt Linguist 中,帮助翻译人员理解。
7.3 处理 UI 设计师中的文本
如果你在 .ui 文件中写了文本,lupdate 会自动提取,无需额外处理。但要注意,在代码中动态修改 UI 控件的文本时,仍需要按上述方式处理。
7.4 QML 中的国际化
如果使用 QML,使用 qsTr() 代替 tr():
qml
Text {
text: qsTr("Hello World")
}
常见问题与解决
| 问题 | 解决方案 |
|---|---|
| 翻译不生效 | 检查 .qm 路径是否正确,确认 installTranslator 在创建界面之前调用 |
| 部分文本没翻译 | 确认所有文本都用 tr() 包裹,重新运行 lupdate |
| 切换语言后界面没变 | 需要手动调用 retranslateUi() 刷新界面,或者重写 changeEvent |
.qm 加载失败 |
检查文件名是否匹配,用绝对路径测试;资源文件路径用 :/ 前缀而非 qrc:/ |
| 乱码问题 | 确保源文件用 UTF-8 编码保存 |
完整项目结构
MyApp/
├── MyApp.pro
├── translations.qrc
├── main.cpp
├── mainwindow.h
├── mainwindow.cpp
├── mainwindow.ui
├── MyApp_zh_CN.ts # 源翻译文件
├── MyApp_ja.ts
├── MyApp_ko.ts
└── translations/ # 资源目录
├── MyApp_zh_CN.qm # 二进制翻译文件
├── MyApp_ja.qm
└── MyApp_ko.qm
总结
整个流程可以概括为四个命令:
tr()------ 代码中标记需要翻译的文本lupdate------ 提取文本生成.ts文件linguist------ 翻译并保存lrelease/ 发布 ------ 生成.qm文件QTranslator------ 程序中加载