鍍金池/ 教程/ C/ 國際化(上)
Qt 容器和算法拾遺
自定義 model 之一
反走樣
Hello, world!
Qt 容器類之關(guān)聯(lián)存儲(chǔ)容器
QStringListModel
拖放技術(shù)之一
狀態(tài)欄
QTreeWidget
拖放技術(shù)之二
通用算法
event()
Qt 學(xué)習(xí)之路(18): Qt 標(biāo)準(zhǔn)對(duì)話框之 QInputDialog
Qt 容器類之遍歷器和隱式數(shù)據(jù)共享
QListWidget
Meta-Object 系統(tǒng)
事件接收與忽略
Qt 學(xué)習(xí)之路(tip): parent 參數(shù)
Qt 標(biāo)準(zhǔn)對(duì)話框之 QColorDialog
QPainter(續(xù))
國際化(下)
漸變填充
自定義委托
創(chuàng)建 shared library
model-view 架構(gòu)
Graphics View Framework
自定義拖放數(shù)據(jù)對(duì)象
QSortFilterProxyModel
國際化(上)
組件布局
自定義 Model 之三
事件過濾器
QDirModel
Hello, world!(續(xù))
Qt 標(biāo)準(zhǔn)對(duì)話框之 QFileDialog
自定義 model 之二
深入了解信號(hào)槽
坐標(biāo)變換
剪貼板操作
QTableWidget
QByteArray 和 QVariant
創(chuàng)建一個(gè)對(duì)話框(下)
Qt 學(xué)習(xí)之路(32): 一個(gè)簡易畫板的實(shí)現(xiàn)(Graphics View)
文本文件讀寫
自定義事件
編寫跨平臺(tái)的程序
MainWindow
初探信號(hào)槽
Qt 學(xué)習(xí)之路(17): Qt 標(biāo)準(zhǔn)對(duì)話框之 QMessageBox
繪圖設(shè)備
菜單和工具條(續(xù))
二進(jìn)制文件讀寫
QString
事件(event)
菜單和工具條
QPainter
Qt 容器類之順序存儲(chǔ)容器
進(jìn)程間交互
API 文檔的使用
創(chuàng)建一個(gè)對(duì)話框(上)
一個(gè)簡易畫板的實(shí)現(xiàn)(QWidget)

國際化(上)

2D 繪圖部分基本告一段落,還在想下面的部分要寫什么,本來計(jì)劃先說下 view-model 的相關(guān)問題,但是前面看到有朋友問關(guān)于國際化的問題,所以現(xiàn)在先來說說 Qt 的國際化吧!

Qt 中的國際化的方法有很多,常用的有使用 QTextCodec 類和使用 tr()函數(shù)。前者將編碼名稱寫到代碼里面,除非你使用 Unicode 編碼,否則國際化依然是一個(gè)問題;后者就不會(huì)有這個(gè)問題,并且這也是 Qt 推薦的做法。因此,我們主要來說使用 tr()函數(shù)的方法進(jìn)行應(yīng)用程序的國際化。

我們先來看一個(gè)很簡單的 MainWindow。為了清楚起見,這里只給出了 cpp 文件的內(nèi)容:


#include "mainwindow.h" 

MainWindow::MainWindow(QWidget *parent) 
        : QMainWindow(parent) 
{ 
        QMenuBar *menuBar = new QMenuBar(this); 
        QMenu *fileMenu = new QMenu(tr("&File"), menuBar); 
        QAction *newFile = new QAction(tr("&New..."), fileMenu); 
        fileMenu->addAction(newFile); 
        QAction *openFile = new QAction(tr("&Open..."), fileMenu); 
        fileMenu->addAction(openFile); 
        menuBar->addMenu(fileMenu); 
        setMenuBar(menuBar); 

        connect(openFile, SIGNAL(triggered()), this, SLOT(fileOpen())); 
} 

MainWindow::~MainWindow() 
{ 

} 

void MainWindow::fileOpen() 
{ 
        QFileDialog *fileDialog = new QFileDialog(this); 
        fileDialog->setWindowTitle(tr("Open File")); 
        fileDialog->setDirectory("."); 
        if(fileDialog->exec() == QDialog::Accepted) { 
                QString path = fileDialog->selectedFiles()[0]; 
                QMessageBox::information(NULL, tr("Path"), tr("You selected\n%1").arg(path)); 
        } else { 
                QMessageBox::information(NULL, tr("Path"), tr("You didn't select any files.")); 
        } 
} 

這是一個(gè)很簡單的類,運(yùn)行結(jié)果想必大家也都非常清楚:就是一個(gè)主窗口,上面有一個(gè)菜單欄,一個(gè) File 菜單,里面有兩個(gè)菜單項(xiàng):

http://wiki.jikexueyuan.com/project/learn-road-qt/images/55.png" alt="" />

之所以把運(yùn)行圖貼出來,是為了大家能夠看清,在代碼中的&符號(hào)實(shí)際在界面中顯示成為一條下劃線,標(biāo)記出這個(gè)菜單或者菜單項(xiàng)的快捷鍵。按照代碼,當(dāng)我們點(diǎn)擊了 Open 時(shí),會(huì)彈出一個(gè)打開文件的對(duì)話框:

http://wiki.jikexueyuan.com/project/learn-road-qt/images/56.png" alt="" />

這里的 slot 里面的代碼在前文中已經(jīng)詳細(xì)介紹過。也許你會(huì)問,為什么要用這種麻煩的寫法呢?因?yàn)槲覀冊(cè)?jīng)說過,使用 static 函數(shù)實(shí)際上是直接調(diào)用系統(tǒng)的對(duì)話框,而這種構(gòu)造函數(shù)法是 Qt 自己繪制的。這對(duì)我們后面的國際化是有一定的影響的。

好了,都已經(jīng)準(zhǔn)備好了,下面開始進(jìn)行國際化。所謂國際化,實(shí)際上不僅僅是把界面中的各種文字翻譯成另外的語言,還有一些工作是要進(jìn)行書寫方式、貨幣等的轉(zhuǎn)換。比如,阿拉伯書寫時(shí)從右向左的,這些在國際化工作中必須完成。但是在這里,我們只進(jìn)行最簡單的工作,就是把界面的文字翻譯成中文。

首先,我們需要在 pro 文件中增加一行:


TRANSLATIONS += myapp.ts

myapp.ts 是我們需要?jiǎng)?chuàng)建的翻譯文件。這個(gè)文件的名字是任意的,不過后綴名需要是 ts。然后我們打開命令提示符,進(jìn)入到工程所在目錄,比如我的是 E:\My Documents\Workspace\Qt\MyApp,也就是pro 文件所在的文件夾,然后輸入命令


lupdate MyApp.pro 

,如果你出現(xiàn)的是命令不存在,請(qǐng)注意將 Qt 的 bin 目錄添加到環(huán)境變量中。此時(shí),如果更新的數(shù)目,說明 ts 文件創(chuàng)建成功:

http://wiki.jikexueyuan.com/project/learn-road-qt/images/57.png" alt="" />

最后一行是說,找到7個(gè)需要翻譯的原文字,0個(gè)已經(jīng)存在。也就是說,這個(gè)文件是新建的。這時(shí)你會(huì)在工程目錄下找到這個(gè) myapp.ts 文件。也許你會(huì)奇怪,為什么這里還會(huì)說已存在的數(shù)目呢?因?yàn)?Qt 這個(gè)工具很智能的能夠識(shí)別出已經(jīng)存在的文字和修改或新增的文字,這樣在以后的工作中就不需要一遍遍重復(fù)翻譯以前的文字了。這也就是為什么這個(gè)工具的名字是“l(fā)update”的原因,因?yàn)樗恰皍pdate”,而不僅僅是生成。

如果你有興趣的話,可以用記事本打開這個(gè) ts 文件,這個(gè)文件實(shí)際上是一個(gè) XML 文件,結(jié)構(gòu)很清晰。不過,我們要使用專業(yè)的翻譯工具進(jìn)行翻譯。Qt 提供了一個(gè)工具,Qt Linguist,你可以在開始菜單的Qt 項(xiàng)下面的 Tools 中找到。用它可以打開我們的 ts 文件,然后進(jìn)行我們的翻譯工作:

http://wiki.jikexueyuan.com/project/learn-road-qt/images/58.png" alt="" />

完全翻譯完成后保存文件,然后在文件菜單下有個(gè)“發(fā)布”。點(diǎn)擊這個(gè)按鈕,工程目錄下會(huì)有一個(gè)myapp.qm 文件,這就是我們翻譯得到的文件。Qt 的 qm 文件實(shí)際上是二進(jìn)制格式的,因此它經(jīng)過了高度的優(yōu)化,體積很小。

下面我們要修改 main()函數(shù),使之加載這個(gè) qm 文件:


int main(int argc, char *argv[]) 
{ 
        QApplication a(argc, argv); 
        QTranslator qtTranslator; 
        qtTranslator.load("myapp.qm"); 
        a.installTranslator(&qtTranslator); 
        MainWindow w; 
        w.resize(800, 600); 
        w.show(); 
        return a.exec(); 
}

注意,QTranslator 類實(shí)際是在 QtCore 下面的。代碼還是很清晰:創(chuàng)建一個(gè) QTranslator 對(duì)象,然后加載 qm 文件,然后將這個(gè)對(duì)象安裝到 QApplication 類。好了,現(xiàn)在大功告成,重新編譯后運(yùn)行下程序吧!

咦?怎么還是英文的?哪里有錯(cuò)誤了呢?這里往往令人疑惑,其實(shí),這是由于我們使用 load()函數(shù)加載qm 文件時(shí)使用的是相對(duì)路徑,這樣直接 load(“myapp.qm”),其實(shí)會(huì)在當(dāng)前編譯后的 exe 所在目錄下尋找這個(gè) qm 文件,所以,只要我們把 qm 文件同 exe 放在同一目錄下,再次運(yùn)行:

http://wiki.jikexueyuan.com/project/learn-road-qt/images/59.png" alt="" />

現(xiàn)在,這個(gè)界面已經(jīng)是中文了吧!其實(shí),這一小細(xì)節(jié)已經(jīng)說明,qm 文件其實(shí)是動(dòng)態(tài)加載到 exe 文件中的,而不是直接編譯進(jìn)去的。這一點(diǎn)為我們進(jìn)行動(dòng)態(tài)切換語言提供了基礎(chǔ)。

本文出自 “豆子空間” 博客,請(qǐng)務(wù)必保留此出處 http://devbean.blog.51cto.com/448512/193918