[Qt Topic] – 中文化研習,做一個多語言的簡易天氣預報器
[Qt Topic] – 中文化研習做一個多語言的簡易天氣預報器
日期 2010-04-01 -- 2010-04-02
平台 Qt SDK v2010.02.1 + Windows Xp
聲明 文章作者僅在Intel軟件網絡
和CSDN博客
發表本文如有轉載請注明出處。
[1] 簡單地使用 QTextCodec 和 tr 配合
在默認情況下我們直接在源碼中使用中文比如 setWindowTitle(tr(" 中文化研習 ")); 則會在運行界麵發現中文亂碼。遇到這種問題如果無需考慮國際化則可以直接使用 QTextCodec 設置編碼方式
QTextCodec::setCodecForTr(QTextCodec::codecForName("GB18030"));
該語句需要包含頭文件 #include <QTextCodec> 。
選擇 GB18030 而不是 GBK 或者 GB2312 是因為前者的漢字收錄更豐富並向下兼容了後兩者。但是在嵌入式設備上如手機或 MP3 並不一定支持 GB18030 。
而既然是 setCodecForTr 那麼就應該在第一次對 tr() 的調用之前設置編碼方式一般應該在 main() 函數中緊接 Qapplication 對象創建後設置。 tr() 用來返回一個翻譯過的文本版本在編寫代碼的過程中對每一個用戶可見的文本都應該加上該函數。
這樣設置了以後基本的中文顯示如按鈕文本、窗口標題以及文本編輯區域都可以得到良好的顯示。
值得一提的是如果出現的不是亂碼而是問號則可能是字符編碼內無該字的編碼。另外一種問題是如果出現的是方框正方形而不是亂碼則可能是無該指定字體可以通過設置 QFont 嚐試解決該問題。
[2] 關於使用 QString 來顯示中文
一是使用 toLocal8Bit 和 fromLocal8Bit 。比如下述代碼就可以良好地顯示中文
QString gbText; gbText = gbText.fromLocal8Bit("漢化"); btn = new QPushButton(gbText);
通過這種方式可以使用係統的本地 8 位編碼格式。
二是通過 QString 和 QTextCodec 結合設置在 const char * 和 Qstring 之間轉換時使用的編碼格式比如下述代碼也可以使得漢字良好顯示
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("GB18030")); QString str = "漢化"; textEdit->append(str);
[3] 使用 Qt 翻譯家
Qt 提供了外部的翻譯文件隻要對需要進行翻譯的文本使用 tr() 函數然後在 .pro 工程文件中添加 TRANSLATIONS = localizer.ts 這裏的文件名自然要根據具體需要設置。之後使用 lupdate 命令如 lupdate localizer.pro 生成 localizer.ts 。接著用 linguist 打開 localizer.ts 並在文件裏麵進行相應文本的翻譯保存後發布生成 localizer.qm 。
至此在包含了頭文件 #include <QTranslator> 後即可以安裝翻譯家將相應的文本進行翻譯
QTranslator translator; translator.load(":/localizer"); app.installTranslator(&translator);
此時再運行程序則可以發現界麵上的文本已經得到翻譯了。
補充在上述代碼中 localizer.qm 是由 qrc 文件指定位置的本例中 localizer.qm 相對於 qrc 文件的位置是“ /localizer.qm ”所以添加的時候使用“ :/localizer ”。而如果 qm 文件相對於 qrc 文件的位置是“ /translator/localizer.qm ”則需要指定為“ :/translator/localizer.qm ”。
[4] 文件讀寫中的中文
這裏以讀取 Google 的天氣 API 為例。
Google 的中文天氣 API 為 https://www.google.com/ig/api?hl=zh_cn&weather= 等號後麵加城市名比如“ beijing ”或者“ hongkong ”。
該 API 是以 XML 格式給出信息而如果我們不加以修飾地直接讀取該 XML 文件的話則會出現如“ é£ åï ¼ ä ¸åã é£ é ”之類的亂碼。
針對這種情況可以先使用不一定必須使用 QString 存放信息因為可以用 QTextCodec 對 QString 進行編碼格式的設置
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
這樣的話就可以以相應的編碼格式進行文件讀取。運行後可以看到中文顯示正常。
同樣地使用其它方式進行文件讀取的話也可以使用類似設置編碼格式的方法。比如使用 QTextStream 時如果希望使用特定的編碼進行讀寫則可以使用該類的成員函數 setCodec() 。
[5] 可動態切換語言的天氣預報器
關於這個話題可以精煉成以下幾點具體的完整代碼將會在後麵給出
1 、動態的語言切換的實現是通過在運行時用戶進行語言選擇時觸發的信號引起相應槽的運作。比如可以設置一個語言菜單供用戶選擇語言我在這裏隻設置了英語和中文。當用戶點擊菜單選項的時候利用 QTranslator 進行不同 qm 文件的重新載入然後再重繪可見文本。所以這就要求一是用戶可見的文本應該用 tr() 函數處理畢竟這不是一樣很大的負擔最好將其養成習慣二是生成用戶可見文本的代碼最好放在一個函數裏為了取名有意義可以取做 retranslateUi() 。
void QWR::retranslateUi(){ enAct->setText(tr("&English")); cnAct->setText(tr("&Chinese")); languageMenu->setTitle(tr("&Language")); cityLabel->setText(tr("City")); runBtn->setText(tr("&Run")); setWindowTitle(tr("QWeatherReporter")); }
2 、天氣預報的功能是通過調用 Google API 實現的需要注意的是溫度單位在國內外的不同。如果當前用戶選擇英文就選擇英文 API 同樣的如果用戶選擇中文就設置 URL 為中文 API 地址。這就需要在編碼的時候進行判斷判斷的方式有多種。
QString url; if(cnAct->isChecked()){ url = "https://www.google.com/ig/api?hl=zh_cn&weather="; url.append(cityBox->text()); }else{ url = "https://www.google.com/ig/api?hl=en&weather="; url.append(cityBox->text()); } request.setUrl(QUrl(url));
3 、 Google 天氣 API 給的結果是 XML 格式的所以參考 [4] 中提到的要設置編碼格式。正確讀取 XML 數據後再根據結點名稱獲取具體的天氣數據如最高溫、最低溫以及日期等。
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); QString xmlFile = reply->readAll(); if(xmlFile.size() < 1000){ //Error city information resultBox->setText("No Such City!"); return ; }
4 、最後就是將天氣預報的結果呈現出來。
[ 結語 ] 這個小程序我給放到了 https://qwr.sf.net 各位如果有興趣去可以下載完整源碼。由於陸續有朋友郵件我說需要源碼其實sf.net上有所以我給放到了CSDN資源上地址為https://download.csdn.net/source/2231965
[補充]後來我在寫一個程序的時候發現使用GB18030或者GBK、GB2312也一樣在我的機子上運行是OK的但是拿到其他機子同樣的係統卻出現了亂碼這令我很是驚訝。不過後來還是尋求了一個解決方案就是設置當前編碼為本地編碼
QTextCodec::setCodecForTr(QTextCodec::codecForLocale()); QTextCodec::setCodecForCStrings(QTextCodec::codecForLocale());
這可能是樓下的朋友提出的不管輸什麼城市都是“No Such City”的原因可以如此修改一番。
最後更新:2017-04-02 04:26:02