目录
[5.2.将 .qm 嵌入资源文件(避免外置)](#5.2.将 .qm 嵌入资源文件(避免外置))
[5.3.翻译 Qt 内置控件文本(如 QMessageBox)](#5.3.翻译 Qt 内置控件文本(如 QMessageBox))
1.简介
在 Qt 中,QTranslator是实现多语言切换的核心类,它通过加载预编译的翻译文件(.qm),将程序中标记的字符串替换为目标语言。
实现原理:
1.关键类与工具
QTranslator:加载.qm翻译文件,提供字符串翻译映射。QCoreApplication::installTranslator():为应用安装翻译器,使tr()标记的字符串被翻译。lupdate:从代码中提取待翻译字符串,生成.ts(XML 格式)源文件。Qt Linguist:可视化翻译工具,编辑.ts文件并保存。lrelease:将翻译完成的.ts编译为二进制.qm文件(程序运行时加载)。
2.核心逻辑
- 用
tr()包裹所有需要翻译的字符串(tr()会关联当前类的 "上下文",确保翻译准确)。 - 通过工具链生成并编译翻译文件。
- 程序启动 / 切换语言时,加载对应语言的
.qm文件,安装到应用中,并刷新界面文本。
2.QTranslator说明
1.load()
load() 是 QTranslator 最核心的接口,用于加载 .qm 文件,返回 bool(true 表示加载成功)。所有重载均支持本地路径、资源路径(:/xxx.qm)。
| 重载签名 | 功能说明 | 参数解析 | 典型场景 |
|---|---|---|---|
bool load(const QString &fileName, const QString &directory = QString(), const QString &searchDelimiters = QString(), const QString &suffix = QString()) |
加载指定路径的 .qm 文件 |
- fileName:文件名(可含后缀,如 zh_CN.qm);- directory:文件所在目录(可选,为空则使用当前工作目录);- searchDelimiters:搜索分隔符(极少用,默认空);- suffix:文件后缀(默认 .qm) |
加载本地 / 资源文件系统中的自定义 .qm(最常用) |
bool load(const QLocale &locale, const QString &baseName, const QString &prefix = QString(), const QString &directory = QString(), const QString &suffix = QString()) |
按区域设置自动匹配翻译文件 | - locale:目标区域(如 QLocale::Chinese/QLocale("en_US"));- baseName:文件名前缀(如 app);- 其他参数同上 |
自动匹配系统 / 指定区域的翻译文件(如 baseName=app + locale=zh_CN → 加载 app_zh_CN.qm) |
bool load(const QByteArray &data, const QString &fileName = QString()) |
从内存字节数组加载翻译数据 | - data:.qm 文件的二进制数据;- fileName:标识名(仅用于日志,无实际加载作用) |
加载网络下载 / 内存缓存的 .qm 数据 |
bool load(QLibraryInfo::LibraryLocation location, const QString &fileName, const QString &prefix = QString(), const QString &suffix = QString()) |
加载 Qt 内置翻译文件(Qt6 新增) | - location:Qt 库路径(如 QLibraryInfo::TranslationsPath,指向 Qt 内置翻译文件目录);- 其他参数同上 |
加载 Qt 自带控件的翻译文件(如 qt_zh_CN.qm) |
关键说明:
- 加载失败原因:文件不存在、路径错误、
.qm损坏、Qt 版本不兼容(如 Qt5 编译的.qm无法在 Qt6 加载); - 资源文件加载:路径以
:/开头(如translator.load(":/translations/zh_CN.qm"))。
示例:
cpp
QTranslator trans;
// 方式1:加载本地文件
trans.load("translations/zh_CN.qm");
// 方式2:加载资源文件
trans.load(":/translations/en_US.qm");
// 方式3:按QLocale加载(自动匹配zh_CN)
trans.load(QLocale::Chinese, "app", "_", "translations"); // 加载 translations/app_zh_CN.qm
// 方式4:加载Qt内置翻译文件(Qt6)
QTranslator qtTrans;
qtTrans.load(QLibraryInfo::TranslationsPath, "qt", "_", "zh_CN"); // 加载 qt_zh_CN.qm
2.翻译字符串(核心:translate() 系列)
translate() 是翻译的核心接口,QObject::tr() 底层会调用当前安装的翻译器的 translate() 方法。返回翻译后的字符串,无匹配时返回源文本。
| 重载签名 | 功能说明 | 参数解析 |
|---|---|---|
QString translate(const char *context, const char *sourceText, const char *disambiguation = nullptr, int n = -1) const |
核心翻译接口(支持普通 / 消歧 / 复数翻译) | - context:上下文(tr() 默认为当前类名,如 MainWindow);- sourceText:待翻译的源文本;- disambiguation:消歧符(区分相同源文本的不同含义,如 "Close" 可指 "关闭窗口"/"关闭文件");- n:复数计数(-1 表示非复数,≥0 时处理复数形式) |
QString translate(const char *context, const char *sourceText, const char *disambiguation, int n, const QString &locale) const(Qt6) |
指定区域的翻译(极少用) | 新增 locale:目标区域编码(如 "zh_CN") |
关键说明:
- 上下文一致性:
context必须与lupdate提取的上下文(.ts中的上下文)一致,否则翻译失效; - 复数处理:
n为计数时,需配合.ts中复数规则(如%n file(s)翻译为 "1 个文件"/"5 个文件"); - 消歧符:同一源文本在不同场景有不同翻译时使用(如
tr("Close", "Window")vstr("Close", "File"))。
示例:
cpp
QTranslator trans;
trans.load("translations/zh_CN.qm");
// 普通翻译(上下文Global,源文本"OK")
QString okText = trans.translate("Global", "OK"); // 输出"确定"
// 带消歧符的翻译
QString closeWin = trans.translate("Global", "Close", "Window"); // "关闭窗口"
QString closeFile = trans.translate("Global", "Close", "File"); // "关闭文件"
// 复数翻译
QString file1 = trans.translate("Global", "%n file(s)", nullptr, 1); // "1个文件"
QString file5 = trans.translate("Global", "%n file(s)", nullptr, 5); // "5个文件"
3.翻译器管理接口(父翻译器)
支持设置 "父翻译器",当前翻译器无匹配的翻译时,自动回退到父翻译器查找,实现翻译兜底。
| 接口签名 | 功能说明 | 使用场景 |
|---|---|---|
void setParentTranslator(QTranslator *parent) |
设置父翻译器 | 主翻译器 + 兜底翻译器(如 Qt 内置翻译器作为父翻译器) |
QTranslator *parentTranslator() const |
获取当前父翻译器 | 检查 / 修改父翻译器配置 |
示例:
cpp
// 自定义应用翻译器(业务文本)
QTranslator appTrans;
appTrans.load("app_zh_CN.qm");
// Qt内置翻译器(Qt控件文本,如QMessageBox的"Cancel")
QTranslator qtTrans;
qtTrans.load("qt_zh_CN.qm", QLibraryInfo::path(QLibraryInfo::TranslationsPath));
// 设置父翻译器:appTrans查不到时,自动用qtTrans翻译
appTrans.setParentTranslator(&qtTrans);
// 仅安装appTrans即可,自动兜底到qtTrans
qApp->installTranslator(&appTrans);
4.辅助功能接口
| 接口签名 | 功能说明 | 适用版本 | 使用场景 |
|---|---|---|---|
bool isEmpty() const |
判断翻译器是否加载了有效翻译数据 | Qt5+ | 检查 .qm 是否加载成功(补充 load() 返回值) |
void clear() |
清空翻译器中所有已加载的翻译数据 | Qt5+ | 切换语言前清空旧翻译数据 |
QString language() const |
返回翻译文件的目标语言编码(如 "zh_CN"/"en_US") |
Qt6.2+ | 识别当前翻译器的语言(Qt5 需自行解析 .qm 文件名) |
QStringList translations() const |
返回所有已加载的翻译条目(源文本列表) | Qt6+ | 调试翻译数据,确认是否包含目标字符串 |
示例:
cpp
QTranslator trans;
trans.load("zh_CN.qm");
if (trans.isEmpty()) {
qDebug() << "翻译文件加载为空!";
} else {
qDebug() << "当前翻译语言:" << trans.language(); // Qt6+输出"zh_CN"
qDebug() << "翻译条目数:" << trans.translations().size(); // Qt6+
}
// 清空翻译数据
trans.clear();
3.语言文件制作
Qt 语言文件制作是实现多语言的核心环节,核心产物是 .ts(翻译源文件,XML 格式) 和 .qm(编译后的二进制文件,程序运行加载)。
3.1.前置条件
- 安装 Qt 开发环境(含
lupdate、lrelease工具和Qt Linguist可视化翻译工具); - 代码中已用
tr()/QCoreApplication::translate()标记所有待翻译字符串(需确保类继承QObject并添加Q_OBJECT宏)。
3.2.完整制作流程
1.项目配置(.pro 文件)
在项目的 .pro 文件中声明 TRANSLATIONS 变量,指定要生成的 .ts 文件路径(关键:lupdate 会根据此列表生成 / 更新 .ts)。
cpp
QT += core gui widgets
# 源码/头文件(示例)
SOURCES += main.cpp mainwindow.cpp
HEADERS += mainwindow.h
# 声明翻译文件(建议放在translations子目录,需手动创建)
TRANSLATIONS += translations/zh_CN.ts \
translations/en_US.ts \
translations/ja_JP.ts
# 可选配置(Qt5.11+)
CONFIG += lrelease # 构建项目时自动编译.ts为.qm
CONFIG += embed_translations # 将.qm嵌入程序(无需外置文件)
注意:若未加
CONFIG += lrelease,需手动执行lrelease编译.qm。
2.提取字符串生成 .ts 文件
lupdate 工具会扫描代码中 tr() 标记的字符串,生成 / 更新 .ts 文件(XML 格式,可直接用文本编辑器打开,但推荐用 Qt Linguist 编辑)。
1)Qt 语言家 → 更新翻译 (lupdate) 界面进行操作。

2)命令行操作(推荐批量 / 自动化)
需先配置 Qt 环境变量(如 Qt6.5.0\mingw_64\bin 加入系统 PATH),然后执行:
cpp
# 进入项目根目录
cd /path/to/your/project
# 基础用法:根据.pro文件生成/更新.ts
lupdate your_project.pro
# 进阶用法:指定编码、忽略文件
lupdate your_project.pro -encoding utf-8 -exclude "third_party/*"
lupdate 常用参数:
| 参数 | 说明 |
|---|---|
-encoding <编码> |
指定源码编码(如 utf-8,默认自动识别) |
-exclude <路径> |
忽略指定目录 / 文件(如第三方库代码) |
-ts <文件列表> |
手动指定要生成的.ts 文件(覆盖.pro 中的 TRANSLATIONS) |
-no-obsolete |
移除.ts 中已不存在的字符串(清理无效翻译) |
3.使用 Qt Linguist 翻译 .ts 文件
Qt Linguist 是 Qt 官方可视化翻译工具,支持普通字符串、复数、消歧符翻译,是处理 .ts 的核心工具。操作比较简单,就不在这里赘述了。
4.编译 .ts 为 .qm 文件
1)界面执行发布翻译 (lrelease) ,执行后 translations 目录下会生成对应的 .qm 文件。
2)命令行操作
cpp
# 基础用法:编译单个.ts为.qm
lrelease translations/zh_CN.ts -qm translations/zh_CN.qm
# 进阶用法:批量编译所有.ts
lrelease your_project.pro
# 可选参数:压缩qm、移除未翻译条目
lrelease translations/zh_CN.ts -qm translations/zh_CN.qm -compress -remove-untranslated
lrelease 常用参数:
| 参数 | 说明 |
|---|---|
-compress |
压缩 .qm 文件(减小体积) |
-remove-untranslated |
移除未翻译的字符串(减小 qm 体积) |
-threshold <百分比> |
仅保留翻译完成率≥指定百分比的条目 |
4.多语言示例
在main.cpp中加载指定语言的.qm文件,并安装到应用中。
cpp
#include <QApplication>
#include <QTranslator>
#include <QLocale>
#include <QDir>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// 1. 创建翻译器对象
QTranslator translator;
// 2. 加载qm文件(优先加载系统语言,或指定语言)
QLocale locale = QLocale::system(); // 获取系统语言(如zh_CN、en_US)
// 拼接qm文件路径(需确保路径正确)
QString qmPath = QString("translations/%1.qm").arg(locale.name());
// 加载指定语言(测试用,如强制加载英文)
// QString qmPath = "translations/en_US.qm";
if (translator.load(qmPath)) {
// 3. 安装翻译器到应用(核心步骤)
a.installTranslator(&translator);
qDebug() << "加载翻译文件成功:" << qmPath;
} else {
qDebug() << "加载翻译文件失败:" << qmPath;
// 加载失败时,加载默认英文(可选)
translator.load("translations/en_US.qm");
a.installTranslator(&translator);
}
MainWindow w;
w.show();
return a.exec();
}
实际项目中需支持运行时切换语言(如按钮切换中英),核心逻辑:
- 卸载旧翻译器 → 加载新
.qm→ 重新安装翻译器。 - 刷新所有界面控件的文本(
tr()需重新触发)。
实现示例:
mainwindow.h:
cpp
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTranslator>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
// 切换语言的公共接口
void switchLanguage(const QString &languageCode); // 如"zh_CN"、"en_US"
private slots:
// 按钮点击槽函数(切换中文/英文)
void on_btnZhCn_clicked();
void on_btnEnUs_clicked();
private:
Ui::MainWindow *ui;
QTranslator *m_translator; // 翻译器对象(需全局,避免析构)
// 刷新界面文本(核心:重新设置所有控件的tr()文本)
void refreshUI();
};
#endif // MAINWINDOW_H
mainwindow.cpp:
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QApplication>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
, m_translator(new QTranslator(this)) // 创建翻译器(父对象管理内存)
{
ui->setupUi(this);
// 初始化界面文本(用tr()包裹)
refreshUI();
}
MainWindow::~MainWindow()
{
delete ui;
}
// 切换语言核心逻辑
void MainWindow::switchLanguage(const QString &languageCode)
{
// 1. 卸载旧翻译器
qApp->removeTranslator(m_translator);
// 2. 加载新语言的qm文件
QString qmPath = QString("translations/%1.qm").arg(languageCode);
bool loadOk = m_translator->load(qmPath);
if (loadOk) {
// 3. 安装新翻译器
qApp->installTranslator(m_translator);
qDebug() << "切换语言成功:" << languageCode;
} else {
qDebug() << "切换语言失败,加载默认英文:" << qmPath;
m_translator->load("translations/en_US.qm");
qApp->installTranslator(m_translator);
}
// 4. 刷新界面文本
refreshUI();
}
// 刷新所有控件的文本(必须手动重新设置,因为tr()仅在初始化时生效)
void MainWindow::refreshUI()
{
// 窗口标题
this->setWindowTitle(tr("多语言示例"));
// 按钮文本
ui->btnZhCn->setText(tr("切换为中文"));
ui->btnEnUs->setText(tr("切换为英文"));
// 标签文本
ui->label->setText(tr("欢迎使用Qt多语言功能!"));
}
// 切换中文按钮
void MainWindow::on_btnZhCn_clicked()
{
switchLanguage("zh_CN");
}
// 切换英文按钮
void MainWindow::on_btnEnUs_clicked()
{
switchLanguage("en_US");
}
5.关键注意事项
5.1.tr()的正确使用
必须继承 QObject + Q_OBJECT 宏 :tr()是QObject的成员函数,自定义类需继承QObject并添加Q_OBJECT宏(否则lupdate无法提取字符串)。
cpp
class MyWidget : public QWidget
{
Q_OBJECT // 必须加
public:
MyWidget() {
setWindowTitle(tr("我的窗口")); // 正确
}
};
上下文一致性 :tr()的上下文默认是当前类名,若需跨类共享翻译,可使用QCoreApplication::translate()指定上下文:
cpp
// 上下文为"Global",所有地方用此上下文可共享翻译
QString text = QCoreApplication::translate("Global", "确定");
避免动态拼接字符串 :tr()无法识别拼接的字符串,需拆分后翻译:
cpp
// 错误:tr无法提取"共" + num + "条"
ui->label->setText(tr("共" + QString::number(num) + "条"));
// 正确:用arg()占位符
ui->label->setText(tr("共%1条").arg(num));
5.2.将 .qm 嵌入资源文件(避免外置)
将 .qm 文件加入 qrc 资源文件,程序无需依赖外置文件:
1.创建 translations.qrc 文件:
cpp
<RCC>
<qresource prefix="/translations">
<file>translations/zh_CN.qm</file>
<file>translations/en_US.qm</file>
</qresource>
</RCC>
2.在 .pro 文件中添加:
cpp
RESOURCES += translations.qrc
3.代码中加载资源文件中的 .qm:
cpp
translator.load(":/translations/zh_CN.qm"); // 路径以:/开头
5.3.翻译 Qt 内置控件文本(如 QMessageBox)
Qt 自带控件(如 QMessageBox、QFileDialog)的默认文本("OK"、"取消")需加载 Qt 官方翻译文件:
- 找到 Qt 安装目录下的内置翻译文件(如
Qt6.5.0\translations\qt_zh_CN.qm); - 复制到项目
translations目录,或直接加载:
cpp
QTranslator qtTrans;
// Qt6:通过QLibraryInfo获取内置翻译路径
qtTrans.load("qt_zh_CN.qm", QLibraryInfo::path(QLibraryInfo::TranslationsPath));
qApp->installTranslator(&qtTrans);
// Qt5:手动拼接路径
// qtTrans.load("qt_zh_CN.qm", QCoreApplication::applicationDirPath() + "/translations");
5.4.批量处理多语言文件(脚本化)
若项目有大量语言文件,可编写批处理脚本(.bat/.sh)自动化:
cpp
:: batch.bat(Windows)
@echo off
cd /d %~dp0 # 进入脚本所在目录
:: 更新ts
lupdate your_project.pro
:: 编译所有ts为qm
lrelease your_project.pro
echo 语言文件编译完成!
pause
6.总结
Qt 语言文件制作的核心流程是:
项目配置(.pro)→lupdate提取.ts→Qt Linguist翻译.ts→lrelease编译.qm
Qt 多语言实现的核心是:
- 用
tr()标记待翻译字符串。 - 通过
lupdate/Qt Linguist/lrelease生成.qm文件。 - 代码中加载
.qm并安装翻译器,切换语言时刷新界面。
掌握这些后,可灵活实现静态加载系统语言 、运行时动态切换语言 、翻译兜底等多语言场景需求。