QT中文乱码与国际化支持
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();
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('/') - ); 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 = );
~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,,,,);
pGridLayout->addWidget(m_pUsrLineEdit,,,,);
pGridLayout->addWidget(pPwdLabel,,,,);
pGridLayout->addWidget(m_pPwdLineEdit,,,,);
pGridLayout->setSpacing(); QPushButton* pBtnOK = new QPushButton(tr("Login"));
QPushButton* pBtnCancel = new QPushButton(tr("Cancel")); QHBoxLayout* pBtnLayout = new QHBoxLayout();
pBtnLayout->setSpacing();
pBtnLayout->addWidget(pBtnOK);
pBtnLayout->addWidget(pBtnCancel); QVBoxLayout* pDlgLayout = new QVBoxLayout();
pDlgLayout->setMargin();
pDlgLayout->addLayout(pGridLayout);
pDlgLayout->addStretch();
pDlgLayout->addLayout(pBtnLayout);
pDlgLayout->setSpacing();
setLayout(pDlgLayout); connect(pBtnOK,SIGNAL(clicked()),this,SLOT(accept()));
connect(pBtnCancel,SIGNAL(clicked()),this,SLOT(reject())); setWindowTitle(tr("Login"));
resize(,);
} 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 中文界面
QT中文乱码与国际化支持的更多相关文章
- Qt中文乱码解决思路
最近项目中遇到不少的Qt中文乱码的问题,主要原因是客户的需求比较多,Qt版本有用4的版本的也有用5的版本,并且还有windows与linux跨平台的需求.经常出现个问题是windows的解决了,源代码 ...
- Qt中文乱码问题(比较清楚,同一个二进制串被解释成不同的语言)
文章来源:http://blog.csdn.net/brave_heart_lxl/article/details/7186631 以下是dbzhang关于qt中文乱码问题原因的阐述,觉得不错: 首先 ...
- 解决Qt中文乱码以及汉字编码的问题(UTF-8/GBK)——ubuntu环境设置默认是utf-8,文件编码可使用Encodersoft批量转换
一.Qt环境设置 文件从window上传到Ubuntu后会显示乱码,原因是因为ubuntu环境设置默认是utf-8,Windows默认都是GBK.Windows环境下,Qt Creator,菜单-&g ...
- 解决Qt中文乱码以及汉字编码的问题(UTF-8/GBK)
一.Qt环境设置 文件从window上传到Ubuntu后会显示乱码,原因是因为ubuntu环境设置默认是utf-8,Windows默认都是GBK.Windows环境下,Qt Creator,菜单-&g ...
- Qt 中文乱码解决大全
源地址:http://blog.csdn.net/xcy2011sky/article/details/7168376 解决中文乱码,最好知道乱码是什么格式比如说:utf-8. 解决方案: 1.让整个 ...
- qt 中文乱码 处理QByteArray类型里含中文的数据
qt解析tcp通信传来的xml时,中文有乱码 解决方法: 头文件加入 #include <QTextCodec> QByteArray tmpQBA = m_pSocket->rea ...
- qt中文乱码问题
首先,声明一下,QString 是不存在中文支持问题的,很多人遇到问题,并不是本身 QString 的问题,而是没有将自己希望的字符串正确赋给QString. 很简单的问题,"我是中文&qu ...
- qt 中文乱码
首先呢,声明一下,QString 是不存在中文支持问题的,很多人遇到问题,并不是本身 QString 的问题,而是没有将自己希望的字符串正确赋给QString. 很简单的问题,"我是中文&q ...
- qt中文乱码
刚开始学习qt,经常会遇到中文输出乱码,在网上找了解决办法有下面这个两个办法QTextCodec::setCodecForCStrings(QTextCodec::codecForName(" ...
随机推荐
- C#并行编程(5):需要知道的异步
异步与并行的联系 大家知道"并行"是利用CPU的多个核心或者多个CPU同时执行不同的任务,我们不关心这些任务之间的依赖关系. 但是在我们实际的业务中,很多任务之间是相互影响的,比如 ...
- 简单实现一个EventEmiter
在前端开发中,“发布-订阅”也是“观察者模式”是一种常用的设计模式:之前对设计模式没有过深的认识,直到前段时间在封装一个运用AngularJS封装table组件时,遇到一个难题,那就是AngularJ ...
- win7 64位系统pdf预览
装了Win7 64位以后,发现pdf文件不能正常预览,相信很多朋友也遇到了同样的问题,之前搜索的结果有个办法是安装Foxit的插件(相信有不少原来用Adobe Reader的用户从此改用Foxit了) ...
- tarjan算法讲解
tarjan算法,一个关于 图的联通性的神奇算法.基于DFS算法,深度优先搜索一张有向图.!注意!是有向图.根据树,堆栈,打标记等种种神奇方法来完成剖析一个图的工作.而图的联通性,就是任督二脉通不通. ...
- hdu 5761 Rower Bo 物理题
Rower Bo 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5761 Description There is a river on the Ca ...
- div光标
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"% ...
- CodeSmith 基础用法和例子
〇. 前言 一. 工具设置 CodeSmith默认是不支持中文的,那么我们必须要先设置使其支持中文显示,保存.并且要能够在生成文件中支持中文. [Tools ...
- BZOJ 1207 DP
打一次鼹鼠必然是从曾经的某一次打鼹鼠转移过来的 以打每一个鼹鼠时的最优解为DP方程 #include<iostream> #include<cstdio> #include&l ...
- ISO 7816-4: Annex A: Transportation of APDU messages by T=0
http://www.cardwerk.com/smartcards/smartcard_standard_ISO7816-4_annex-a.aspx Annex A: Transportation ...
- [转载]vs2017与docker
基本需求 系统 win10 vs2017 docker 步骤 1.开启系统的hyper-v 2. 重启电脑 3.安装docker 下载地址:https://docs.docker.com/docker ...