在全球化软件市场中,多语言支持与本地化适配是触达全球用户的核心能力。本章带你从零掌握Qt Quick/QML项目的国际化(i18n)与本地化(l10n)实现,覆盖从字符串翻译到复杂数据格式化的完整流程。
qsTr()标记与翻译字符串Qt提供了成熟的国际化框架,qsTr()是QML中标记可翻译字符串的核心工具。
在QML中直接用qsTr()包裹需要翻译的文本,支持上下文注释、复数格式等场景:
// 基础翻译
Text { text: qsTr("Hello World") }
// 复数形式:根据itemCount自动匹配单复数翻译
property string countText: qsTr("%n item(s)", "", itemCount)
// 带上下文注释:帮助翻译者理解场景
Button { text: qsTr("Save", "Button text for saving the document") }
翻译需遵循四步标准化流程:
lupdate project.pro命令,生成XML格式的.ts翻译源文件.ts文件的内容翻译lrelease project.pro命令,生成二进制.qm翻译文件(运行时加载)QTranslator.load()在应用运行时加载对应语言的.qm文件多语言切换需要C++端的翻译管理器配合QML界面,核心是通过QTranslator动态加载不同语言的.qm文件并触发界面刷新。
创建TranslationManager类统一管理翻译加载与切换:
// TranslationManager.h
#include <QObject>
#include <QTranslator>
#include <QGuiApplication>
class TranslationManager : public QObject
{
Q_OBJECT
Q_PROPERTY(QString currentLanguage READ currentLanguage WRITE setLanguage NOTIFY languageChanged)
public:
explicit TranslationManager(QGuiApplication *app, QObject *parent = nullptr);
QString currentLanguage() const { return m_currentLanguage; }
void setLanguage(const QString &language);
signals:
void languageChanged();
private:
QGuiApplication *m_app;
QTranslator m_translator;
QString m_currentLanguage;
};
// TranslationManager.cpp
void TranslationManager::setLanguage(const QString &language)
{
if (m_currentLanguage == language) return;
// 移除旧翻译
m_app->removeTranslator(&m_translator);
// 加载新翻译(需确保.qm文件在资源路径中)
QString qmFile = QString(":/translations/app_%1.qm").arg(language);
if (m_translator.load(qmFile)) {
m_app->installTranslator(&m_translator);
m_currentLanguage = language;
emit languageChanged(); // 触发界面刷新
}
}
注意:需在main.cpp中注册该类到QML,才能在界面中调用:
qmlRegisterType<TranslationManager>("com.example.translation", 1, 0, "TranslationManager");
在QML中导入翻译管理器,实现语言切换控件与翻译文本的绑定:
import QtQuick 2.15
import QtQuick.Controls 2.15
import com.example.translation 1.0
ApplicationWindow {
id: window
width: 800
height: 600
// 实例化翻译管理器
TranslationManager { id: transManager }
// 语言切换下拉框
ComboBox {
id: languageCombo
anchors.top: parent.top
anchors.right: parent.right
model: ["zh_CN", "en_US", "ja_JP", "de_DE"]
onCurrentTextChanged: transManager.setLanguage(currentText)
}
// 绑定翻译文本
Column {
anchors.centerIn: parent
spacing: 20
Text { text: qsTr("Welcome to My Application"); font.pixelSize: 24 }
Button {
text: qsTr("Click Me")
onClicked: console.log(qsTr("Button clicked!"))
}
}
}
本地化不仅是语言翻译,还要适配不同地区的数据显示习惯,Qt的Locale类可轻松实现这一点。
QML中通过Qt.locale()获取系统区域设置,或手动指定地区,调用格式化方法:
import QtQuick 2.15
Item {
// 获取系统默认区域,也可手动指定:Qt.locale("de_DE")
property var locale: Qt.locale()
// 日期格式化(ShortFormat/ LongFormat)
function formatDate(date) {
return date.toLocaleDateString(locale, Locale.ShortFormat)
}
// 时间格式化
function formatTime(date) {
return date.toLocaleTimeString(locale, Locale.ShortFormat)
}
// 货币格式化
function formatCurrency(amount) {
return Number(amount).toLocaleCurrencyString(locale)
}
// 数字千位分隔符格式化
function formatNumber(num) {
return Number(num).toLocaleString(locale)
}
}
不同地区的显示习惯差异明显:
整合翻译与格式化的实战示例:
import QtQuick 2.15
import QtQuick.Layouts 1.15
Rectangle {
width: 400
height: 300
color: "#f0f8ff"
border.color: "#2c3e50"
radius: 10
property date currentDate: new Date()
property real amount: 1234567.89
property int itemCount: 5
ColumnLayout {
anchors.fill: parent
anchors.margins: 20
spacing: 15
Text {
text: qsTr("Localized Information Panel")
font.bold: true
font.pixelSize: 20
color: "#2c3e50"
Layout.alignment: Qt.AlignHCenter
}
GridLayout {
columns: 2
columnSpacing: 20
rowSpacing: 10
Text { text: qsTr("Current Date:") }
Text { text: currentDate.toLocaleDateString(Qt.locale(), Locale.LongFormat); color: "#2f4f4f" }
Text { text: qsTr("Current Time:") }
Text { text: currentDate.toLocaleTimeString(Qt.locale(), Locale.LongFormat); color: "#2f4f4f" }
Text { text: qsTr("Amount:") }
Text { text: Number(amount).toLocaleCurrencyString(Qt.locale()); color: "#27ae60"; font.bold: true }
Text { text: qsTr("Item Count:") }
Text { text: qsTr("%n item(s)", "", itemCount); color: "#2f4f4f" }
Text { text: qsTr("Formatted Number:") }
Text { text: Number(amount).toLocaleString(Qt.locale()); color: "#2f4f4f" }
}
Button {
text: qsTr("Refresh Data")
Layout.alignment: Qt.AlignHCenter
onClicked: {
currentDate = new Date()
amount = Math.random() * 1000000
itemCount = Math.floor(Math.random() * 10) + 1
}
}
}
}
qsTr("%n item(s)", "", count)这类带占位符的格式.qm文件路径错误或未正确加载,可先用绝对路径调试TranslationManager发出languageChanged信号,触发QML界面更新qsTr("%n item(s)", "", count)格式,让Qt自动处理单复数翻译qsTr()标记Locale格式化日期、时间与温度显示提示:Qt Linguist提供翻译记忆、模糊匹配等专业功能,能大幅提升翻译效率,推荐优先使用。