1. 程式人生 > >Qt 之國際化

Qt 之國際化

簡介

Qt國際化屬於Qt高階中的一部分,本想著放到後面來說,上節剛好介紹了Qt Linguist,趁熱打鐵就一起了解下。

對於絕大多數的應用程式,在剛啟動時,需要載入預設的語言(或最後一次設定的語言)。在使用的過程中,我們也不需要重啟應用程式而實現語言的動態切換。這樣的話,易用性就非常好了。

|

多語言切換

這裡寫圖片描述

要進行多語言的切換,需要執行以下步驟:

  1. 對使用者可見的文字資訊全部使用tr()進行封裝

  2. 提供使用者可以用來切換語言的一種方法。

  3. 對於每一個視窗部件或者對話方塊,重寫changeEvent事件,當事件型別為QEvent::LanguageChange時,翻譯文字進行重新呼叫(為了簡單我把它放在一個單獨的函式translateUI()中)。

原始碼分析

我們來看一個簡單的示例:主介面、設定介面,設定介面可根據選擇不同語言下拉選項實現語言的動態切換!

為了簡單起見,這裡只給出關鍵程式碼(原始碼下載請參考最下面下載地址):

設定介面:setting_dialog.h

typedef enum{
    UI_ZH,
    UI_EN
}LANGUAGE;

Q_DECLARE_METATYPE(LANGUAGE)

設定介面:setting_dialog.cpp

language_combo_box->addItem("chinese", QVariant::fromValue(UI_ZH));
language_combo_box->addItem("english"
, QVariant::fromValue(UI_EN)); qRegisterMetaType<LANGUAGE>("LANGUAGE"); connect(language_combo_box, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &SettingDialog::onIndexChanged); void SettingDialog::changeEvent(QEvent *event) { switch (event->type()) { case
QEvent::LanguageChange: translateUI(); break; default: QDialog::changeEvent(event); } } void SettingDialog::translateUI() { this->setWindowTitle(tr("setting dialog")); info_label->setText(tr("no brothers no programming")); language_label->setText(tr("language")); language_combo_box->setItemText(UI_ZH, tr("chinese")); language_combo_box->setItemText(UI_EN, tr("english")); } void SettingDialog::onIndexChanged() { LANGUAGE language = language_combo_box->currentData().value<LANGUAGE>(); emit switchLanguage(language); }

主介面:MainWidget.cpp

connect(setting_dialog, &SettingDialog::switchLanguage, this, &MainWidget::switchLanguage);

void MainWidget::translateUI()
{
    this->setWindowTitle(tr("main widget"));
    welcome_label->setText(tr("welcome to Qt") + QString("26197884/26188347"));
    setting_button->setText(tr("setting"));
    ok_button->setText(tr("ok"));
    cancel_button->setText(tr("cancel"));
}

void MainWidget::setLanguage(LANGUAGE current_language)
{
    this->current_language = current_language;
}

void MainWidget::setTranslator(QTranslator* translator)
{
    this->translator = translator;
}

void MainWidget::changeEvent(QEvent *event)
{
    switch (event->type())
    {
    case QEvent::LanguageChange:
        translateUI();
        break;
    default:
        QWidget::changeEvent(event);
    }
}

void MainWidget::switchLanguage(LANGUAGE language)
{
    QString language_qm;
    switch(language)
    {
    case UI_ZH:
        language = UI_ZH;
        language_qm = QString(":/qm/main_widget_zh");
        break;

    case UI_EN:
        language = UI_EN;
        language_qm = QString(":/qm/main_widget_en");
        break;

    default:
        language = UI_ZH;
        language_qm = QString(":/qm/main_widget_zh");
    }

    if(current_language != language)
    {
        current_language = language;
        translator->load(language_qm);
        Util::writeInit(QString("./user.ini"), QString("language"), QString::number(language, 10));
    }
}

main.cpp

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QString language_value;
    QString language_suffix = QString("zh");
    LANGUAGE language = UI_ZH;
    bool is_read = Util::readInit(QString("./user.ini"), QString("language"), language_value);
    if(is_read)
    {
        language = (LANGUAGE)language_value.toInt();
        if(language == UI_EN)
        {
            language_suffix = QString("en");
        }
    }

    QTranslator translator;  
    translator.load(QString(":/qm/main_widget_") + language_suffix);  
    app.installTranslator(&translator); 

    MainWidget main_widget;
    main_widget.setTranslator(&translator);
    main_widget.setLanguage(language);
    main_widget.show();
    return app.exec();
}

流程:

  1. 進入main(),首先載入預設的語言(或最後一次設定的語言),然後顯示主介面。

  2. 當開啟設定介面後,首先載入當前選擇的語言,然後通過下拉設定語言選項來進行語言切換(設定介面的switchLanguage訊號關聯到主介面的switchLanguage槽中),然後將當前的語言進行儲存。

語言切換後,首先會進入changeEvent函式,判斷當事件型別為QEvent::LanguageChange時,就會執行translateUI函式進行文字重新顯示。

注:

  • Q_DECLARE_METATYPE:如果要使自定義型別或其他非QMetaType內建型別在QVariant中使用,必須使用該巨集 。

  • qRegisterMetaType:如果非QMetaType內建型別要在訊號與槽中使用。

新增翻譯源

為了方便,這裡只介紹中、英文之間的切換。

在pro中新增:

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

選擇:工具->外部->Qt語言家->更新翻譯,則會生成對應的ts檔案。

這裡寫圖片描述

翻譯

使用Qt Linguist開啟要翻譯的ts檔案,對翻譯源進行相應語言的翻譯。

釋出翻譯

選擇:檔案->釋出,就會生成對應的qm檔案。

這裡寫圖片描述

載入翻譯檔案

使用QTranslator來載入生成的qm檔案,就可以讓程式顯示指定的語言。

QTranslator translator;  
translator.load(":/qm/main_widget_zh");  
app.installTranslator(&translator); 

原始碼下載