Qt 的國際化機制允許應用在啟動時加載默認語言,並在運行時無需重啟即可動態切換語言,極大提升用戶體驗。本文系統梳理從源碼標記、翻譯文件生成到動態切換的完整流程,並提供關鍵代碼範例。
tr() 包裹所有可見字符串;.pro 中聲明 TRANSLATIONS,運行 lupdate 生成 .ts 文件;.ts 逐條翻譯;.qm 文件;QTranslator 加載 .qm,qApp->installTranslator() 生效,觸發 QEvent::LanguageChange 重繪 UI。typedef enum { UI_ZH, UI_EN } LANGUAGE;
Q_DECLARE_METATYPE(LANGUAGE) // 允許在 QVariant 中存儲
// setting_dialog.cpp
languageComboBox->addItem("Chinese", QVariant::fromValue(UI_ZH));
languageComboBox->addItem("English", QVariant::fromValue(UI_EN));
qRegisterMetaType("LANGUAGE"); // 信號槽跨線程需註冊
connect(languageComboBox, QOverload::of(&QComboBox::currentIndexChanged),
this, &SettingDialog::onIndexChanged);
void SettingDialog::changeEvent(QEvent *event) {
if (event->type() == QEvent::LanguageChange) translateUI();
else QDialog::changeEvent(event);
}
void SettingDialog::translateUI() {
setWindowTitle(tr("Setting Dialog"));
infoLabel->setText(tr("No brothers no programming"));
languageLabel->setText(tr("Language"));
languageComboBox->setItemText(UI_ZH, tr("Chinese"));
languageComboBox->setItemText(UI_EN, tr("English"));
}
void SettingDialog::onIndexChanged() {
LANGUAGE lang = languageComboBox->currentData().value();
emit switchLanguage(lang); // 發射語言切換信號
}
// MainWidget.cpp
connect(settingDialog, &SettingDialog::switchLanguage, this, &MainWidget::switchLanguage);
void MainWidget::translateUI() {
setWindowTitle(tr("Main Widget"));
welcomeLabel->setText(tr("Welcome to Qt") + " 26197884/26188347");
settingButton->setText(tr("Setting"));
okButton->setText(tr("OK"));
cancelButton->setText(tr("Cancel"));
}
void MainWidget::changeEvent(QEvent *event) {
if (event->type() == QEvent::LanguageChange) translateUI();
else QWidget::changeEvent(event);
}
void MainWidget::switchLanguage(LANGUAGE lang) {
QString qmPath;
switch (lang) {
case UI_ZH: qmPath = ":/qm/main_widget_zh"; break;
case UI_EN: qmPath = ":/qm/main_widget_en"; break;
default: qmPath = ":/qm/main_widget_zh";
}
if (currentLang != lang) {
currentLang = lang;
translator->load(qmPath);
Util::writeInit("./user.ini", "language", QString::number(lang));
}
}
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QString langValue, suffix = "zh";
LANGUAGE lang = UI_ZH;
if (Util::readInit("./user.ini", "language", langValue)) {
lang = (LANGUAGE)langValue.toInt();
if (lang == UI_EN) suffix = "en";
}
QTranslator translator;
translator.load(":/qm/main_widget_" + suffix);
app.installTranslator(&translator);
MainWidget w;
w.setTranslator(&translator);
w.setLanguage(lang);
w.show();
return app.exec();
}
TRANSLATIONS = Resource/main_widget_zh.ts \
Resource/main_widget_en.ts
運行 工具 → 外部 → Qt Linguist → 更新翻譯 生成 .ts,翻譯後發布為 .qm。
QTranslator 被安裝/移除/替換時,Qt 向所有頂層窗口發送此事件,開發者在 changeEvent 中重新調用 tr() 刷新文本。Q_DECLARE_METATYPE + qRegisterMetaType:確保自定義枚舉類型可在 QVariant 與信號槽中安全傳遞。:.qm):將翻譯文件編譯進二進制,避免部署遺漏。Qt 國際化的核心在於「標記 → 提取 → 翻譯 → 發布 → 動態加載」閉環。掌握 QTranslator 與 LanguageChange 事件配合,即可實現無縫熱切換,是專業級 Qt 應用的必備技能。