QT實現多國語言的動態切換
摘要:本文論述瞭如何使用QT實現程式的多語系支援以及多語系的動態切換。
前沿
我們生活中用到的程式大多都是支援單一語言的,比如在中國我們用到的軟體大多是漢語的,也有很少部分使用的是英語的,但是很少有軟體可以實現兩種語言的動態切換。不過隨著近幾年我國的發展支援多國語言的軟體也越來越多,比如上海地鐵售票機,動車組自動售票機等都是支援漢語和英語兩種語言的。使用QT程式設計可以很容易的編寫支援多國語言的軟體。
用QT實現多國語言支援有兩種情況:
第一種:使用UI編輯器來自動生成介面,這種方式實現多語系的動態切換很容易。
第二種:不使用UI編輯器,自己通過親自程式設計來設計應用程式介面,這種方式實現多語系動態切換比較繁瑣,注意不是難;
下面先來介紹第一種的實現方法:
voidMainWindow::ch_language()
{
if(this->languageState)
{
this->languageState=CHINESE ;
this->translator.load("test_ch") ;
this->pOwner->installTranslator(&(this->translator));
}
else
{
this->languageState=ENGLISH ;
this->translator.load("test_en") ;
this->pOwner->installTranslator(&(this->translator));
}
}
第二種方式就不那麼簡單了,除了要執行上述函式外還要將將要切換的語言重新設定一遍。
voidMainWindow::langChang()
{
if(this->langState)
{
this->langState=CHINESE ;
this->translator.load("test_ch") ;
this->pOwner->installTranslator(&(this->translator));
}
else
{
this->langState=ENGLISH ;
this->translator.load("test_en") ;
this->pOwner->installTranslator(&(this->translator));
}
this->setWindowTitle(QObject::tr("hello world"));
this->addFileAction->setText(QObject::tr("NewFile"));
this->langChAction->setText(QObject::tr("Chinese"));
this->playAction->setText(QObject::tr("Play")); ;
this->stopAction->setText(QObject::tr("Stop"));
this->menuBar()->addMenu(QObject::tr("FIle")) ;
this->menuBar()->addMenu(QObject::tr("Control"));
}
因此比較麻煩,特別是介面比較繁瑣的時候,將是很麻煩的。
下面來討論為什麼第一種方法為什麼不需要重新設定語言了。因為使用Ui時有這個函式
voidMainWindow::changeEvent(QEvent *e)
{
QMainWindow::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
ui->retranslateUi(this);//這裡實現語言翻譯器的更新。
下面就來看一下QT中如何製作多語言包。
實現方法:
為了支援國際化最關鍵的地方是製作多國語言包,然後再實現動態切換。QT裡面既可以採用命令列也可以採用Qt Creator的介面操作來生成,這裡我們利用Qt Creator來生成多國語言包。基本流程是,先生成ts檔案,然後生成qm檔案,最後通過QTranslator類來載入qm檔案,實現多語言包的切換。注意:為了更全面地實現多語言包,在程式中所有涉及到介面中的按鈕或者選單中的文字顯示,都必須使用 QObject::tr("...") 的方式將顯示的內容包裹起來,這樣做的原因是:只有添加了QObject::tr()的標記,生成ts檔案的時候程式才會認為被QObject::tr()包裹的地方是需要製作多語言的,從而在ts中預留出位置。
1> 生成ts檔案
在QT的專案檔案(.pro)中新增:TRANSLATIONS = XXX.ts YYY.ts(如果是多行,則用 \ 分割)
然後執行【工具】-》【外部】-》【QT語言家】-》【更新翻譯(lupdate)】,如下圖所示,執行完之後專案下就會生成對應的XXX.ts、YYY.ts檔案。
注意:如果專案中包含ui檔案,如:FORMS += ZZZ.ui,則在生成的ts檔案中包含所有ui檔案上的字元顯示,而且,在製作ui檔案時預設情況下介面上的文字顯示都是通過QObejct::tr(" ")包裹的,因為在預設情況下ui中的所有控制元件都存在一個屬性:可翻譯的,就代表了預設用QObject::tr()嵌套了。
2. 生成qm檔案
利用QT語言家:Linguist開啟生成的ts檔案,將裡面需要翻譯的地方寫上對應的語言,如下圖所示:
ts檔案翻譯完成後,執行Qt Creator中的【工具】-》【外部】-》【QT語言家】-》【部署翻譯(lrelease)】就會生成最終要用到的qm檔案,如下圖所示:
3. 載入qm語言包
到這裡qm語言包製作完成,工作就完成了一大半了。接下來的任務就是在程式碼中實現語言包的載入,即:根據不同的選擇載入不同的語言包。
voidLHSyncClientPrivate::InitUiByLanguage(const QString strLanguage)
{
if (strLanguage.isEmpty())
{
return;
}
QString strLanguageFile;
if (strLanguage.compare("en") ==0)
{
strLanguageFile = qApp->applicationDirPath()+QString("/languages/%1/%2").arg(LHT_SYNCCLIENT_VERSION_PRODOCUTNAME).arg(LHT_SYNCCLIENT_EN_FILE);
}
else if(strLanguage.compare("zh") == 0)
{
strLanguageFile =qApp->applicationDirPath() + QString("/languages/%1/%2").arg(LHT_SYNCCLIENT_VERSION_PRODOCUTNAME).arg(LHT_SYNCCLIENT_ZH_FILE);
}
if (QFile(strLanguageFile).exists())
{
m_translator->load(strLanguageFile);
qApp->installTranslator(m_translator);
}
else
{
qDebug() << "[houqd]authclient language file does not exists ...";
}
}
其中,m_translator即為QTranslator例項,在類的建構函式中賦值:m_translator = new QTranslator;實現過程很簡單,就是取得語言包的絕對路徑,然後利用QTranslator來載入它,最後利用qApp->installTranslator(m_translator)來安裝。
4. 重新設定介面顯示
重新設定介面的顯示,這一步是很多人容易忘記的一步,如果這兒被忽略了,往往就無法完成語言的切換,即:重新設定一下需要顯示的元素,該過程是在上面InitUiByLanguage過程之後進行的,相關程式碼如下:
voidLHSyncClientPrivate::RetranslateUi()
{
m_wgtSync->setWindowTitle(tr("DriveClient"));
//! 左側同步資訊
m_btnSynchronizing->setText(tr("Synchronizing"));
m_btnSynchronized->setText(tr("Synchronized"));
//! 右側面板
m_lblSyncStatus->setText(tr("looking for fileschanges..."));
m_lblShowRecordsNum->setText(tr("There are n records..."));
m_btnSyncOrPause->setText(tr("SyncOr Pause"));
m_btnClearAll->setText(tr("Clearall"));
m_btnSyncOrPause->setText(tr("SyncOr Pause"));
m_btnClose->setText(tr("Close"));
m_actSync->setText(tr("SyncInfo"));
}
實現效果:
好了,到這裡整個語言包的製作過程就基本完成了。這裡還需要提及一點在網盤客戶端實現時的設計思路:由於網盤在登入前和登入後可操作的選單是不一樣的,要涉及一種動態載入的方式,可以實現一個UiLoader的外掛,它實現所有的窗體載入(即LoadUi()返回QWidget控制代碼)、選單載入、語言切換,在這些功能中可能UiLoader外掛並不完成具體的工作,而僅僅是實現訊號的轉發功能。同樣,也需要實現一個邏輯控制外掛,它負責所有的選單邏輯,而對於每個窗體則由各自的窗體外掛自行完成。多語言切換的實現效果如下:
切換為中文:
切換後效果:
加油,堅持每天的學習!!