一、多語言界面設計概述
1.在程序設計階段,程序代碼中每一個用戶可見的字符串都用tr()函數封裝,以便Qt提取界面字符串,用於生成翻譯資源文件。用UI設計器可視化設計窗體時統一用一種語言。
2.在項目配置文件.pro文件中設置需要導出的翻譯文件.ts文件,使用lupdate工具掃描項目文件中需要翻譯的字符串,並生成翻譯文件。
3.使用Qt的Linguist程序打開生成的翻譯文件,將程序中的字符串翻譯為需要的語言,如將所有中文字符串翻譯成英文。
4.使用lrelease工具編譯翻譯好的翻譯文件,生成更為緊湊的“.qm”文件,實現不同的語言界面。
二、tr()函數的使用
為了讓qt可以提取用戶可見的字符串,需要對每個字符串使用tr()函數封裝。tr()是QObject的一個靜態函數,在使用了Q_OBJECT宏定義的類或QObject的子類中,都可以直接使用tr()函數,否則需要使用QObject::tr()調用。或者在類定義中用Q_DECLARE_TR_FUNCTIONS宏把tr()函數添加到類中之后,再直接調用tr()函數。
定義:QString QObject::tr(const char *sourceText, const char *disambiguation = Q_NULLPTR, int n = -1);
其中,sourceText是源字符串, disambiguation是為翻譯者提供額外信息的字符串,用於對一些容易混淆的地方作說明。
注意事項:
- 盡量使用常量字符串,不要使用字符串變量。以下使用lupdate工具提取項目中的字符串時,將不能提取“不能刪除記錄”這個字符串。
char *errorStr = "不能刪除記錄"; QString str2 = tr(errorStr);
- 使用字符串變量時,需要用Qt_TR_NOOP()宏進行標記。
const char *cities[4] = { Qt_TR_NOOP("Beijing"), Qt_TR_NOOP("Shanghai"), Qt_TR_NOOP("Qingdao"), Qt_TR_NOOP("Wuhan") }; for(int i = 0; i < 4; i++) comboBox->addItem(tr(cities[i]));
- tr()不能使用拼接的動態字符串。
//錯誤 LabCellPos->setText(tr("第" + QString::number(current.row()) + "行")); //正確 LabCellPos->setText(tr("第 %1 行").arg(current.row()));
- Qt_NO_CAST_FROM_ASCII的作用。在一個需要翻譯為多語言的應用程序中,如果編寫程序時忘了對某個字符串使用tr()函數,lupdate生成的翻譯資源文件就會遺漏這個字符串。為了避免這種疏忽錯誤,可以在項目配置文件(.pro文件)中添加如下的定義。
DEFINES += Qt_NO_CAST_FROM_ASCII
三:VS項目中配置多語言步驟
步驟:
1.創建項目,對用到的每個字符串以上規則的前提下加入tr()函數。
2.右擊項目,點擊Qt中的Create New Traslation File
(sample_zh.ts和sample_en.ts)創建英文和中文的ts文件
3.右擊sample_zh.ts或者sample_en.ts,使用lupdate生成翻譯的資源文件
4.使用Qt Linguist翻譯ts文件
5.右擊sample_zh.ts或者sample_en.ts,使用lrelease在項目源程序目錄下生成qm文件sample_zh.qm或者sample_en.qm
四:調用翻譯文件改變界面語言
case1:
啟動項目時獲取系統語言,改變界面語言:
__CheckLocale()獲取系統語言。參考鏈接:https://www.cnblogs.com/foreversdf/p/12900497.html
std::string locale = __CheckLocale(); if (locale.find("zh") != std::string::npos || locale.find("CN") != std::string::npos) { m_translator.load("translations/sample_zh"); m_translatorQt.load("translations/qt_zh_CN"); qApp->installTranslator(&m_translator); qApp->installTranslator(&m_translatorQt); } else { m_translator.load("translations/sample_en"); m_translatorQt.load("translations/qt_en"); qApp->installTranslator(&m_translator); qApp->installTranslator(&m_translatorQt); }
case2:
動態切換語言,對於大型軟件來說不推薦動態切換語言,一般都需要重啟后進行設置。
void MainWindow::on_actionChinese_triggered() { qApp->removeTranslator(m_translator); delete trans; m_translator= new Qtranslator; m_translator->load("translatsions/sample_zh"); qApp->installTranslator(m_translator); ui->retranslateUi(this); //刷新界面字符串 } void MainWindow::on_actionEnglish_triggered() { qApp->removeTranslator(m_translator); delete trans; m_translator= new Qtranslator; m_translator->load("translatsions/sample_en"); qApp->installTranslator(m_translator); ui->retranslateUi(this); //刷新界面字符串 }