Qt 之國際化
簡介
Qt國際化屬於Qt高階中的一部分,本想著放到後面來說,上節剛好介紹了Qt Linguist,趁熱打鐵就一起了解下。
對於絕大多數的應用程式,在剛啟動時,需要載入預設的語言(或最後一次設定的語言)。在使用的過程中,我們也不需要重啟應用程式而實現語言的動態切換。這樣的話,易用性就非常好了。
|
多語言切換
要進行多語言的切換,需要執行以下步驟:
對使用者可見的文字資訊全部使用tr()進行封裝
提供使用者可以用來切換語言的一種方法。
對於每一個視窗部件或者對話方塊,重寫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();
}
流程:
進入main(),首先載入預設的語言(或最後一次設定的語言),然後顯示主介面。
當開啟設定介面後,首先載入當前選擇的語言,然後通過下拉設定語言選項來進行語言切換(設定介面的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);