首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

Qt 國際化與動態多語言切換完整實戰指南

     編輯:關於C

前言

Qt 的國際化機制允許應用在啟動時加載默認語言,並在運行時無需重啟即可動態切換語言,極大提升用戶體驗。本文系統梳理從源碼標記、翻譯文件生成到動態切換的完整流程,並提供關鍵代碼範例。

核心流程概覽

  1. 源碼標記:使用 tr() 包裹所有可見字符串;
  2. 提取翻譯源:在 .pro 中聲明 TRANSLATIONS,運行 lupdate 生成 .ts 文件;
  3. 翻譯:用 Qt Linguist 打開 .ts 逐條翻譯;
  4. 發布:在 Linguist 中「發布」生成二進制 .qm 文件;
  5. 加載與切換:QTranslator 加載 .qm,qApp->installTranslator() 生效,觸發 QEvent::LanguageChange 重繪 UI。

關鍵代碼實現

1. 定義語言枚舉並註冊元類型

typedef enum { UI_ZH, UI_EN } LANGUAGE;
Q_DECLARE_METATYPE(LANGUAGE) // 允許在 QVariant 中存儲

2. 設置對話框:語言選擇與信號發射

// 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); // 發射語言切換信號
}

3. 主窗口:加載翻譯、持久化配置、響應切換

// 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));
    }
}

4. main.cpp:啟動時加載上次語言

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();
}

.pro 文件配置

TRANSLATIONS = Resource/main_widget_zh.ts \
               Resource/main_widget_en.ts

運行 工具 → 外部 → Qt Linguist → 更新翻譯 生成 .ts,翻譯後發布為 .qm。

關鍵機制解析

  • QEvent::LanguageChange:當 QTranslator 被安裝/移除/替換時,Qt 向所有頂層窗口發送此事件,開發者在 changeEvent 中重新調用 tr() 刷新文本。
  • Q_DECLARE_METATYPE + qRegisterMetaType:確保自定義枚舉類型可在 QVariant 與信號槽中安全傳遞。
  • 資源文件 (:.qm):將翻譯文件編譯進二進制,避免部署遺漏。

總結

Qt 國際化的核心在於「標記 → 提取 → 翻譯 → 發布 → 動態加載」閉環。掌握 QTranslator 與 LanguageChange 事件配合,即可實現無縫熱切換,是專業級 Qt 應用的必備技能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved