網站首頁 編程語言 正文
簡介
????????有些軟件需要開發多語言界面版本,如中文版和英文版,并且在軟件里可以方便地切換界面語言。Qt為多語言界面提供了很好的支持,使用Qt的一些規則和工具,可以很方便地為應用程序開發提供多界面支持。
? ? ? ? 使用Qt 開發多語言界面應用程序,主要包括以下幾個步驟 。
? (1)在程序設計階段,程序代碼中每 一 個用戶可見的字符串都用 tr()函數封裝,以便 Qt 提取界面字符串用千生成翻譯資源文件。用 UI 設計器可視化設計窗體時統一用 一種語言,如漢語 。
? ?(2)? 在項目配置文件 (.pro 文件)中設置需要導出的翻譯文件 (.ts 文件)名稱,使用lupdate工具掃描項目文件中需要翻譯的字符串,并生成翻譯文件 。
? ?(3)? 使用 Qt 的 Linguist 程序打開生成的翻譯文件,將程序中的字符串翻譯為需要的語 言 ,如將所有中文字符串翻譯為英文 。
? ( 4)? 使用 lrelease 工具編譯翻譯好的翻譯文件, 生成更為緊湊的 ". qm" 文件 。
? ( 5)? 在應用程序中用 QTranslator 調用不同的 " .qm" 文件,實現不同的語 言界面。
1.tr()函數使用
????????為了讓 Qt 能自動提取程序中用戶可見的字符串,對千每個字符串都需要使用 tr()函數封裝 。tr()是 QObject 的 一個靜態函數 ,在使用了 Q—OBJECT 宏定義的類或 QObject 的子類中,都可以直接使用 tr()函數,否則需要使用 QObject::tr()進行調用。或者在類定義中用 Q_DECLARE_TR_FUNCTIONS 宏把 tr()函數添加到類中之后 ,再直接調用 tr()函數 。
????????tr()函數的定義?:
QString QObject::tr(const char *sourceText, const char *disambiguation=Q_NULLPTR,int? n = -1);
?????????其中, sourceText 是源字符串 disambiguation 是為翻譯者提供額外信息的字符串,用于對 些容易混淆的地方作說明,內容如下:
LabCellPos = new QLabel(tr( 當前單元格:"), this); QMessageBox::information(this, tr("信息"), tr( "信息提示?"), QMessageBox::Yes) ; QString strl= tr("左右", "大約的意思"); QString str2 = tr("左右", "掌握、控制的意思");
使用 tr()函數,需要注意以下事項。
?????????① 盡量使用常量字符串 不要使用字符串變量。在 tr()函數中應直接傳遞字符串常量,而不是用變星傳遞字符串,如下面的代碼使用了字符串變量,使用lupdate 工具提取項目中的 字符串時 將不能提取“不能刪除 這個字符串。
char *errorStr="不能刪除記錄"; QString str2=tr(errorStr);
????????②使用字符串變量時需要用 Qt_TR_NOOP() 宏進行標記 。若要 tr()函數中使用字符串變量 需要在定義字符串的地方用 Qt_TR_NOOP() 宏進行標記,這在使用字符串數組時比較有用。 例如:
canst char *cities[4]={Qt_TR_NOOP("Beijing"), Qt_TR_NOOP(" Shanghai"), Qt_TR_NOOP("Qingdao"), Qt_TR_NOOP("Wuhan")}; for (int i=O; i<4; i++) { comboBox->additem(tr(cities[i])) ; }
????????③tr()不能使用拼接的動態字符串。 tr()不能使用拼接的動態字符串,例如,下面的用法是錯誤的:
LabCellPos->setText(tr("第") + QString::number(current.row())+ tr("行");
正確的方式如下:
LabCellPos->setText(tr("第%1行").arg (current.row()));
翻譯的字符串是“第%1行 ”, 然后再用 QString 的arg() 去替換占位符 "%1 "的內容。
????????④Qt_NO_CAST_FROM_ ASCII 的作用。在一個需要翻譯為多語言的應用程序中,如果編寫 程序時忘了對某個字符串使用 tr() 函數, lupdate 生成的翻譯資源文件就會遺漏這個字符串。 為了避免這種疏忽錯誤,可以在項目配置文件(. pro 文件)中添加如下的定義:
DEFINES+= Qt_NO_CAST_FROM_ ASCII
????????這樣在編譯時,會禁止從 con char* 到QString 的隱式轉換 ,強制每個字符串都必須使用 tr()或 QLatinlString()封裝, 避免出現遺漏未翻譯的字符串。?
2.生成語言翻譯文件
????????要生成多語言界面相關的翻譯文件,除了之前所說的在對每個字符串 都使用 tr()函數封裝之外,還需要在項目配置文件 (.pro 文件)中使用 TRANSLATIONS 定義語言翻譯文件 (. ts 文件), 并使用 lupdate 工具生成語言翻譯文件。
????????在項目的配置文件(*.pro)中增加如下的設置語句:
???????? TRANSLATIONS += lang_Chs.ts? ? ?\
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?lang_Eng.ts
????????在項目設計期間,任何時候都可以使用lupdate 工具生成或更新翻譯文件,方法是單擊Qt Creator 主菜單的 “Tools”- "External" - "Qt 語言家”- "Update Translations(lupdate)" 菜單項, 若項目的源程序目錄下沒有lang_Chs.ts、lang_Eng.ts (具體名稱可變)這兩個文件,就會自動生成,如果 文件已經存在,則會更新這兩個文件的內容。
3.使用 Qt Linguist 翻譯 ts 文件
????????生成的 lang_Chs.ts、lang_Eng.ts 文件內包含了項目源程序和 UI 界面里的所有字符 串,使用 Qt Linguist 可以將這些字符串翻譯為需要的語言版本。在 Qt 安裝后的程序組里可以找到 Qt Linguist 軟件。
????????lang_Chs.ts 是中文界面的翻譯文件,由于源程序的界面就是用中文設計的,所以無需再 翻譯 lang_Eng.ts 是英文翻譯文件,需要將提取的所有中文字符串翻譯為英文。
? ? ? ? 在Linguist 軟件中打開文件lang_Eng.ts, 當第一次打開一個 ts 文件時, Linguist 會出現如下圖所示的語言設置對話框,用千設置目標語言和所在國家和地區。這個對話框也可以通過 Linguist 主菜單的“編輯“一“翻譯文件設置”菜單項調出。lang_Eng.ts 是用于英文界面的翻譯文件,所以選擇語言 “English", 國家/地區可選擇 “UnitedStates”。
????????打開 lang_Eng.ts 文件后的 Linguist 軟件界面如下圖所示。左側”上下文”列表里列出了項目中的所有窗口或類, 這個項目有4個窗口。”字符串”列表里列出了從項目的 UI 窗口和代碼文件中提取的字符串,右側“短語和表單”會顯 示窗口界面的預覽或字符串在源程序中出現的代碼段。
????????在”字符串”列表中選擇一個源文后,在下方會出現譯 文編輯框,在此填寫字符串對應的英文譯文。 Linguist 可以 同時打開項目的多個 ts 文件,在選中一個源文后,在下方會 出現對應的多個語 言的譯文編輯框 ,可以同時翻譯為多個語言版本。
?4.調用翻譯文件改變界面語言
4.1. 生成 qm 文件
????????使用 Linguist 軟件編輯翻譯文件,將所有字符串都翻譯后,在 Qt Creator 中單擊主菜單項 "Tools" -- "External" -- "Qt 語言家”-- "Release Translations(lrelease) ",會在項目源程序目錄 下生成與 ts 文件對應的 qm 文件,這是更為緊湊的翻譯文件。 會生成??lang_Chs.qm和? lang_Eng.qm。
?2. 項目啟動時設置界面語言
????????使用 QTranslator 類設置界面的不同語言版本,需在應用程序啟動時設置界面語言翻譯文件, 即在 main()函數中進行處理 。項目 在main.cpp 的代碼如下:?
#include "mainwindow.h" #include <QApplication> #include <QTranslator> #include <QSettings> QTranslator *trans=NULL ; QString readSetting(); int main (int argc , char *argv[]) { QApplication app(argc, argv); trans = new QTranslator; QString curLang=readSetting (); //讀取語言設置 if (curLang== "EN") { trans->load ("lang_Eng.qm"); } else { trans->load("lang_Chs.qm"); } app.installTranslator(trans); MainWindow w; w.show(); return app.exec(); } QString readSetting() { //注冊表讀取上 次設置的語言 QString organization = "Language"; QString appName= "test"; QSettings settings(organization, appName) ; QStri n g Language=settings.value ("Language"," EN").toString(); return Language ; }
????????這里定義了 個全局變 trans, main.cpp 里定義了個函數 readSetting(), 用千從注冊表里讀取上次設置的界面語言版本。注冊表里數據的讀取和寫入使用到 QSettings 類,在main()函數中,創建 QTranslator 類的對象 trans 后,調用 readSetting()函數從注冊表里讀取 上次的語言版本,若為 “EN" ,就用 load()函數載入編譯后的英文翻譯文件 lang_Eng.qm, 否則就載入中文翻譯文件lang_Chs.qm ,再執行 app.installTranslator(trans) ,就可以給應用程序安裝翻譯器,實現需要的界面版本。
?3. 動態切換語言
????????在軟件運行時可以動態切換語 ,即 啟軟件就可以切換界面語言,測試程序的主窗 口上有“中文”和 “English" 兩個工具欄按鈕,用千實現中文和英文界面的切換。 下面是這兩個 按鈕的響應代碼:?
void MainWindow::on_actLang_CN_triggered() {//中文界面 qApp->removeTranslator(trans); if (trans) { delete trans; trans = NULL; } trans = new Qtranslator; trans->load("lang_Chs.qm"); qApp->installTranslator(trans); //這一步很關鍵 ui->retranslateUi(this); //刷新界面字符串 QSettings settings("WWB-Qt", "test"); settings.setValue ("Language ", "CN") ; } void Maindow::on_actLang_EN_triggered() {//英文界面 qApp->removeTranslator(trans) ; if (trans) { delete trans; trans = NULL; } trans=new Qtranslator; trans->load( " sampl6_l_en.qm"); qApp->installTranslator(trans) ; //這一步很關鍵 ui->retranslateUi(this) ; //刷新界面字符串 QSettings settings( "WWB-Qt","test"); settings.setValue ("Language", "EN"); }
????????一個應用程序只能加載一個翻譯器 ,因為在 main()函數里已 經加載了一個翻譯器 ,所以需 要先移除當前的翻譯器,才能重新創建新的翻譯器,加載翻譯文件,并為應用程序重新加載新翻譯器。
????????完成這些后還必須調用 UI的retranslateUi() 函數來刷新界面。
????????retranslateUi()函數是在窗口的 ui _" 頭文件中自動生成的 ,如 mainwindow. ui 主窗口對應的 頭文件 ui _mainwindow.h 里就有函數 retranslateUi(),這個函數使用 QApplication::translate() 函數將 所有界面字符串進行翻譯 ,類似于 tr()函數的功能。
????????窗口在被創建時會自動調用此 retranslateUi() 函數,在程序運行中動態切換界面語言時,必須 手工調用此 retranslateUi() 函數,才可以立即更新界面語言。
????????若不是用 Designer 設計的窗口,而是完全由代碼實現的窗口界面,需要專門設計一個 retranslateUi()?函數,將所有界面字符串用 tr() 函數進行翻譯,并在動態切換語言時調用此函數。? 很顯然 這樣做比較麻煩,特別是當軟件比較大窗口非常多時。所以,大型的軟件在重新設置語言版本后 一般要求重新啟動軟件才生效 ,在程序啟動時根據上次的設置加載一次翻譯器即可。
????????按鈕響應代碼的最后是將設置的語言版本寫入本地配置文件 ,以便下次程序啟動時自動加載相應的語言。
原文鏈接:https://blog.csdn.net/zhangchuan7758/article/details/122165980
相關推薦
- 2022-07-20 Python對PDF文件的常用操作方法詳解_python
- 2022-06-01 SQL為什么不建議執行超過3表以上的多表關聯查詢_MsSql
- 2022-05-02 深入了解Python?中線程和進程區別_python
- 2022-04-20 C語言數據結構與算法時間空間復雜度基礎實踐_C 語言
- 2022-06-08 Python使用PyYAML庫讀寫yaml文件的方法_python
- 2022-06-01 利用20行Python?代碼實現加密通信_python
- 2022-03-03 CSS樣式修改不換行顯示省略號及多行顯示省略號
- 2022-10-21 Python?NumPy教程之數組的基本操作詳解_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支