QT國際化支持
Qt內部采用的全Unicode編碼,這從根本上保證了多國語界面實現的正確性和便捷性。Qt本身提供的linguist工具,用來實現翻譯過程十分方便。MFC中利用資源DLL切換資源,或使用多個RC文件進行不同語言版本編譯等方法都十分麻煩,如果你曾經使用過MFC,QT解決多語言問題的便捷性絕對會讓你感覺是一種享受。本文討論以下幾個方面內容:
1、QT中解決中文亂碼的方法;
2、QT中實現國家化支持。
3、對話框實現多語言
一、中文亂碼
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();
二、國際化支持
QT中實現多國語言,建議在程序中直接英文,而后通過不同的翻譯文件實現多語言的支持。實現多國語的步驟有如下幾步(提及的工具均為QT自帶):
?在需要被翻譯的字符串前面加標識tr,如QString str=tr(“hello,world!”);這很重要,因為翻譯工具會把源碼中tr標識的字符串提取出來,翻譯成其他語言,如果沒有用tr標識的,不會被工具提取。在界面中輸入的文字,默認已經是加上tr的了,所以在翻譯時也能看見。
?在QT工程文件*.pro中增加一項:TRANSLATIONS+=*.ts,擴展名為.ts是翻譯的源文件。一般會在命名中把區域加進去,更好的注釋這些文件是用于什么語言的,可以根據“語言_國家”的形式形成文件名。比如中命名為myapp_zh_CN.ts,zh表示簡體中文,而CN表示的就是中華人名共和國。可以參照ISO語言與國家代碼標準: http://blog.csdn.net/alicehyxx/archive/2009/12/06/4952318.aspx
?使用lupdate工具提取翻譯源文件,【運行】中輸入CMD,打開命令行窗口,利用CD命令切換到QT安裝目錄的BIN目錄中,而后輸入:
lupdate *.pro
*.pro包含pro文件的全路徑。lupdate會解析*.pro文件,生成TRANSLATIONS中的*.ts文件,這些文件可以被linguist工具打開,按照提示一個一個的翻譯成需要的文件并保存。
?重復以上兩步!
(針對以上兩步,VS2005中可以直接使用菜單【QT】à【Create new translations File】創建,如果文件已經存在,可以通過圖1.1菜單進行更新。)
圖1.1 VS2005_lupdate
?使用lrelease工具發布翻譯文件的二進制文件,這樣在程序運行時載入會大大的加快速度。在命令行窗口中繼續輸入:
lrelease *.ts
*.ts包含ts文件的全路徑。這個工具會提示你多少語句被翻譯,多少被忽略了等。生成的文件是*.qm,與同名的*.ts只是換了一個擴展名。這個就是我們程序需要使用到的文件。
(VS2005中可以使用圖1.1中的菜單lrelease來實現該步驟)
?使用*.qm文件。程序可以通過兩種方式加載翻譯文件,一種硬編碼方式,直接指定加載的語言,代碼如下:
int main(int argc,char* argv[])
{
QApplication app(arcg,argv);
QTranslator translator;
translator.load(“basicdraw_zh_CN”);
app.installTranslator(&translator);
}
另外一種是自動判斷翻譯當前的locale,再裝入相應的翻譯文件,如下所示:
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()返回以“語言_國家”形式形成的字符串,比如zh_CN。
至于通過控件,比如ComboBox選擇語言,并實現動態切換,以后再討論。
三、對話框實現多語言
在實際程序中實現多語言切換,需要生成的qm文件應該包含兩個:
?QT運行庫相關的qm文件:在QT安裝目錄的translations目錄下,存在需要*.ts文件,利用lrelease命令生成對應的qm文件。
?利用“二”中的步驟生成程序本身需要的*.ts文件,并生成qm文件。
QApplication支持多個翻譯文件,并根據后加入先使用的搜索順序進行搜索。
具體代碼如下:
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運行庫翻譯器
- 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;
- };
程序中使用了兩個
QTranslator
對象,在app
利用函數
installTranslator()
進行翻譯器安裝時,并沒有拷貝qm
文件,而是在需要的時候在qm文件中進行查找。也即是說:QTranslator在load以后,并沒有把qm文件中的數據拷貝一份。如果qm在這期間被刪除或修改,對程序都是有影響的。擴展開來,QTranslator必須保證要一直有效,如果在函數中定義的局部變量,函數結束后就自動釋放掉了,那么翻譯工作就不能正常進行。
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中文界面
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

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