QT中文亂碼與國際化支援
轉自:http://blog.csdn.net/alicehyxx/article/details/4960571
QT國際化支援
Qt內部採用的全Unicode編碼,這從根本上保證了多國語介面實現的正確性和便捷性。Qt本身提供的linguist工具,用來實現翻譯過程十分方便。MFC中利用資源DLL切換資源,或使用多個RC檔案進行不同語言版本編譯等方法都十分麻煩,如果你曾經使用過MFC,QT解決多語言問題的便捷性絕對會讓你感覺是一種享受。本文討論以下幾個方面內容:
1、 QT中解決中文亂碼的方法;
2、 QT中實現國家化支援。
3、 對話方塊實現多語言
一、 中文亂碼
1、 在程式中直接使用中文,需要在程式中加入以下程式碼:
- #include <QTextCodec>
- int main(int argc, char **argv)
- {
- QApplication app(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、 解決讀取中文檔案中文的亂碼
- QFile file("xxxx.txt");
- QTextStream stream(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[])
- {
- QApplication app(argc, argv);
- QTextCodec::setCodecForLocale(QTextCodec::codecForLocale());
- // 安裝QT執行庫翻譯器
- QTranslator translatorQT;
- {
- QStringList environment = QProcess::systemEnvironment();
- QString str;
- 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't find the translation file for Chinese!");
- }
- else
- {
- qDebug() << QObject::tr("Please set the environment variable QTDIR");
- }
- }
- // 安裝程式自身翻譯器
- QTranslator translatorApp;
- {
- QString strLanguageDir = QCoreApplication::applicationDirPath();
- strLanguageDir.append("/Language/");
- QString strFilePath = QApplication::applicationFilePath();
- QString strFileName = 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't Find The Translation's File For Chinese!");
- }
- }
- CDialogLogin dlg;
- return dlg.exec();
- }
DialogLogin.h
- #pragma once
- #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("User Name:"));
- 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("User Name or Password is wrong!"),QMessageBox::Yes);
- m_pUsrLineEdit->setFocus();
- }
- }
其中英文介面如圖:
圖1.2 英文介面
中文介面如圖:
圖1.3 中文介面
相關文章
- Sql server 國際化的支援,查詢亂碼SQLServer
- 配置CLion管理Qt專案國際化支援QT
- Qt入門(12)——Qt國際化QT
- QT中文顯示亂碼解決QT
- QT6 國際化QT
- qt亂碼QT
- ?HeyUI完成國際化支援啦????UI
- Spring Boot應用的國際化與本地化支援Spring Boot
- 嵌入式QT SQL中文亂碼問題解決QTSQL
- qt5亂碼QT
- QT筆記之解決QT5.2.0和VS2012中文亂碼 以及在Qt Creator中文報錯QT筆記
- 一種國際化Qt應用程式的方法QT
- matplotlib 圖示 中文亂碼, 與 wordcloud 詞雲圖 中文亂碼 解決方法Cloud
- mysql中文亂碼MySql
- secureCRT中文亂碼Securecrt
- oracle 中文亂碼Oracle
- PHP中文亂碼PHP
- gedit中文亂碼
- PLSQL中文亂碼SQL
- gitk中文亂碼Git
- 國際C語言混亂程式碼大賽C語言
- Django國際化與本地化指南Django
- java web 中文亂碼JavaWeb
- JS cookie 中文亂碼JSCookie
- 使用gettext模組翻譯Python3原始碼以支援國際化Python原始碼
- 一個解決VC++程式國際化的類,解決亂碼問題C++
- 使用Whisper框架快速為專案新增國際化支援框架
- Android國際化(多語言)實現,支援8.0Android
- 中文轉換成unicode字元,實現國際化Unicode字元
- Get提交方式中文亂碼
- JD-GUI中文亂碼GUI
- EasyUI 中文亂碼問題UI
- oracle中文顯示亂碼Oracle
- RHEL中文亂碼解決
- HttpClient 解決中文亂碼HTTPclient
- MSSQL中文亂碼問題SQL
- Java 中文 亂碼問題Java
- jsp 中文亂碼急救JS