QT國(guó)際化支持
Qt內(nèi)部采用的全Unicode編碼,這從根本上保證了多國(guó)語(yǔ)界面實(shí)現(xiàn)的正確性和便捷性。Qt本身提供的linguist工具,用來(lái)實(shí)現(xiàn)翻譯過(guò)程十分方便。MFC中利用資源DLL切換資源,或使用多個(gè)RC文件進(jìn)行不同語(yǔ)言版本編譯等方法都十分麻煩,如果你曾經(jīng)使用過(guò)MFC,QT解決多語(yǔ)言問(wèn)題的便捷性絕對(duì)會(huì)讓你感覺(jué)是一種享受。本文討論以下幾個(gè)方面內(nèi)容:
1、QT中解決中文亂碼的方法;
2、QT中實(shí)現(xiàn)國(guó)家化支持。
3、對(duì)話框?qū)崿F(xiàn)多語(yǔ)言
一、中文亂碼
1、在程序中直接使用中文,需要在程序中加入以下代碼:
- #include<QTextCodec>
- int main( int argc, char **argv)
- {
- QApplicationapp(argc,argv);
- QTextCodec*codec=QTextCodec::codecForName( "GB2312" );
- QTextCodec::setCodecForLocale(codec);
- QTextCodec::setCodecForCStrings(codec);
- QTextCodec::setCodecForTr(codec);
- …………
- return app.exec();
- }
這樣在程序中使用tr(“中文”)或者直接使用“中文”了;
2、解決讀取ini文件中中文亂碼
QSettings settings("xxxx.ini",QSettings::IniFormat);
settings.setIniCodec(QTextCodec::codecForName("GB2312")); settings.beginGroup("company");
3、解決讀取中文文件中文的亂碼
- QFilefile( "xxxx.txt" );
- QTextStreamstream(file,QIODevice::ReadOnly);
- stream.setCodeC(QTextCodec::codecForName( "GB2312" ));
- stream.readAll();
二、國(guó)際化支持
QT中實(shí)現(xiàn)多國(guó)語(yǔ)言,建議在程序中直接英文,而后通過(guò)不同的翻譯文件實(shí)現(xiàn)多語(yǔ)言的支持。實(shí)現(xiàn)多國(guó)語(yǔ)的步驟有如下幾步(提及的工具均為QT自帶):
?在需要被翻譯的字符串前面加標(biāo)識(shí)tr,如QString str=tr(“hello,world!”);這很重要,因?yàn)榉g工具會(huì)把源碼中tr標(biāo)識(shí)的字符串提取出來(lái),翻譯成其他語(yǔ)言,如果沒(méi)有用tr標(biāo)識(shí)的,不會(huì)被工具提取。在界面中輸入的文字,默認(rèn)已經(jīng)是加上tr的了,所以在翻譯時(shí)也能看見(jiàn)。
?在QT工程文件*.pro中增加一項(xiàng):TRANSLATIONS+=*.ts,擴(kuò)展名為.ts是翻譯的源文件。一般會(huì)在命名中把區(qū)域加進(jìn)去,更好的注釋這些文件是用于什么語(yǔ)言的,可以根據(jù)“語(yǔ)言_國(guó)家”的形式形成文件名。比如中命名為myapp_zh_CN.ts,zh表示簡(jiǎn)體中文,而CN表示的就是中華人名共和國(guó)??梢詤⒄誌SO語(yǔ)言與國(guó)家代碼標(biāo)準(zhǔn): http://blog.csdn.net/alicehyxx/archive/2009/12/06/4952318.aspx
?使用lupdate工具提取翻譯源文件,【運(yùn)行】中輸入CMD,打開(kāi)命令行窗口,利用CD命令切換到QT安裝目錄的BIN目錄中,而后輸入:
lupdate *.pro
*.pro包含pro文件的全路徑。lupdate會(huì)解析*.pro文件,生成TRANSLATIONS中的*.ts文件,這些文件可以被linguist工具打開(kāi),按照提示一個(gè)一個(gè)的翻譯成需要的文件并保存。
?重復(fù)以上兩步!
(針對(duì)以上兩步,VS2005中可以直接使用菜單【QT】à【Create new translations File】創(chuàng)建,如果文件已經(jīng)存在,可以通過(guò)圖1.1菜單進(jìn)行更新。)
圖1.1 VS2005_lupdate
?使用lrelease工具發(fā)布翻譯文件的二進(jìn)制文件,這樣在程序運(yùn)行時(shí)載入會(huì)大大的加快速度。在命令行窗口中繼續(xù)輸入:
lrelease *.ts
*.ts包含ts文件的全路徑。這個(gè)工具會(huì)提示你多少語(yǔ)句被翻譯,多少被忽略了等。生成的文件是*.qm,與同名的*.ts只是換了一個(gè)擴(kuò)展名。這個(gè)就是我們程序需要使用到的文件。
(VS2005中可以使用圖1.1中的菜單lrelease來(lái)實(shí)現(xiàn)該步驟)
?使用*.qm文件。程序可以通過(guò)兩種方式加載翻譯文件,一種硬編碼方式,直接指定加載的語(yǔ)言,代碼如下:
int main(int argc,char* argv[])
{
QApplication app(arcg,argv);
QTranslator translator;
translator.load(“basicdraw_zh_CN”);
app.installTranslator(&translator);
}
另外一種是自動(dòng)判斷翻譯當(dāng)前的locale,再裝入相應(yīng)的翻譯文件,如下所示:
int main(int argc,char* argv[])
{
QApplication app(arcg,argv);
QString locale = QLocale::system().name();
QTranslator translator;
translator.load(QString(“basicdraw_”) + locale);
app.installTranslator(&translator);
}
其中QLocale::system().name()返回以“語(yǔ)言_國(guó)家”形式形成的字符串,比如zh_CN。
至于通過(guò)控件,比如ComboBox選擇語(yǔ)言,并實(shí)現(xiàn)動(dòng)態(tài)切換,以后再討論。
三、對(duì)話框?qū)崿F(xiàn)多語(yǔ)言
在實(shí)際程序中實(shí)現(xiàn)多語(yǔ)言切換,需要生成的qm文件應(yīng)該包含兩個(gè):
?QT運(yùn)行庫(kù)相關(guān)的qm文件:在QT安裝目錄的translations目錄下,存在需要*.ts文件,利用lrelease命令生成對(duì)應(yīng)的qm文件。
?利用“二”中的步驟生成程序本身需要的*.ts文件,并生成qm文件。
QApplication支持多個(gè)翻譯文件,并根據(jù)后加入先使用的搜索順序進(jìn)行搜索。
具體代碼如下:
main.cpp
- #include"stdafx.h"
- #include<QtGui/QApplication>
- #include<QtGui/QtGui>
- #include"DialogLogin.h"
- int main( int argc, char *argv[])
- {
- QApplicationapp(argc,argv);
- QTextCodec::setCodecForLocale(QTextCodec::codecForLocale());
- //安裝QT運(yùn)行庫(kù)翻譯器
- QTranslatortranslatorQT;
- {
- QStringListenvironment=QProcess::systemEnvironment();
- QStringstr;
- bool bFinded= false ;
- foreach(str,environment)
- {
- if (str.startsWith( "QTDIR=" ))
- {
- bFinded= true ;
- break ;
- }
- }
- if (bFinded)
- {
- str=str.mid(6);
- bFinded=translatorQT.load( "qt_" +QLocale::system().name(),str.append( "/translations/" ));
- if (bFinded)
- app.installTranslator(&translatorQT);
- else
- qDebug()<<QObject::tr( "Can'tfindthetranslationfileforChinese!" );
- }
- else
- {
- qDebug()<<QObject::tr( "PleasesettheenvironmentvariableQTDIR" );
- }
- }
- //安裝程序自身翻譯器
- QTranslatortranslatorApp;
- {
- QStringstrLanguageDir=QCoreApplication::applicationDirPath();
- strLanguageDir.append( "/Language/" );
- QStringstrFilePath=QApplication::applicationFilePath();
- QStringstrFileName=strFilePath.right(strFilePath.size()-strFilePath.lastIndexOf( '/' )-1);
- strFileName=strFileName.left(strFileName.indexOf( '.' ));
- strFileName.append( '_' );
- strFileName.append(QLocale::system().name());
- bool bFinded=translatorApp.load(strFileName,strLanguageDir);
- if (bFinded)
- app.installTranslator(&translatorApp);
- else
- {
- qDebug()<<QObject::tr( "Can'tFindTheTranslation'sFileForChinese!" );
- }
- }
- CDialogLogindlg;
- return dlg.exec();
- }
DialogLogin.h
- #pragmaonce
- #include<QtGui/QDialog>
- class QLineEdit;
- class CDialogLogin: public QDialog
- {
- Q_OBJECT
- public :
- CDialogLogin(QWidget*parent=0);
- ~CDialogLogin( void );
- public slots:
- virtual void accept();
- private :
- QLineEdit*m_pUsrLineEdit;
- QLineEdit*m_pPwdLineEdit;
- };
程序中使用了兩個(gè)
QTranslator
對(duì)象,在app
利用函數(shù)
installTranslator()
進(jìn)行翻譯器安裝時(shí),并沒(méi)有拷貝qm
文件,而是在需要的時(shí)候在qm文件中進(jìn)行查找。也即是說(shuō):QTranslator在load以后,并沒(méi)有把qm文件中的數(shù)據(jù)拷貝一份。如果qm在這期間被刪除或修改,對(duì)程序都是有影響的。擴(kuò)展開(kāi)來(lái),QTranslator必須保證要一直有效,如果在函數(shù)中定義的局部變量,函數(shù)結(jié)束后就自動(dòng)釋放掉了,那么翻譯工作就不能正常進(jìn)行。
DialogLogin.cpp
- #include"stdafx.h"
- #include"DialogLogin.h"
- #include<QtGui/QtGui>
- CDialogLogin::CDialogLogin(QWidget*parent /*=0*/ )
- :QDialog(parent)
- {
- QLabel*pUsrLabel= new QLabel(tr( "UserName:" ));
- QLabel*pPwdLabel= new QLabel(tr( "Password:" ));
- m_pUsrLineEdit= new QLineEdit();
- m_pPwdLineEdit= new QLineEdit();
- m_pPwdLineEdit->setEchoMode(QLineEdit::Password);
- QGridLayout*pGridLayout= new QGridLayout();
- pGridLayout->addWidget(pUsrLabel,0,0,1,1);
- pGridLayout->addWidget(m_pUsrLineEdit,0,1,1,3);
- pGridLayout->addWidget(pPwdLabel,1,0,1,1);
- pGridLayout->addWidget(m_pPwdLineEdit,1,1,1,3);
- pGridLayout->setSpacing(25);
- QPushButton*pBtnOK= new QPushButton(tr( "Login" ));
- QPushButton*pBtnCancel= new QPushButton(tr( "Cancel" ));
- QHBoxLayout*pBtnLayout= new QHBoxLayout();
- pBtnLayout->setSpacing(60);
- pBtnLayout->addWidget(pBtnOK);
- pBtnLayout->addWidget(pBtnCancel);
- QVBoxLayout*pDlgLayout= new QVBoxLayout();
- pDlgLayout->setMargin(30);
- pDlgLayout->addLayout(pGridLayout);
- pDlgLayout->addStretch(40);
- pDlgLayout->addLayout(pBtnLayout);
- pDlgLayout->setSpacing(40);
- setLayout(pDlgLayout);
- connect(pBtnOK,SIGNAL(clicked()), this ,SLOT(accept()));
- connect(pBtnCancel,SIGNAL(clicked()), this ,SLOT(reject()));
- setWindowTitle(tr( "Login" ));
- resize(300,200);
- }
- CDialogLogin::~CDialogLogin( void )
- {
- }
- void CDialogLogin::accept()
- {
- if (m_pUsrLineEdit->text().trimmed()==tr( "lcf" )&&m_pPwdLineEdit->text().trimmed()==tr( "lcf" ))
- {
- QDialog::accept();
- }
- else
- {
- QMessageBox::warning( this ,tr( "Warning" ),tr( "UserNameorPasswordiswrong!" ),QMessageBox::Yes);
- m_pUsrLineEdit->setFocus();
- }
- }
其中英文界面如圖:
圖1.2英文界面
圖1.3中文界面
轉(zhuǎn)自: http://blog.csdn.net/alicehyxx/article/details/4960571
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
