`

QT中文乱码与国际化支持

 
阅读更多

Qt内部采用的全Unicode编码,这从根本上保证了多国语界面实现的正确性和便捷性。Qt本身提供的linguist工具,用来实现翻译过程十分方便。MFC中利用资源DLL切换资源,或使用多个RC文件进行不同语言版本编译等方法都十分麻烦,如果你曾经使用过MFCQT解决多语言问题的便捷性绝对会让你感觉是一种享受。本文讨论以下几个方面内容:

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文件中进行查找。也即是说:QTranslatorload以后,并没有把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 中文界面

 

 

 

 

 

 

分享到:
评论

相关推荐

    Qt之解决QSettings中文乱码问题源码

    在使用Qt进行应用程序开发时,有时会遇到QSettings类处理中文数据时出现乱码的问题。QSettings类是Qt提供的一种用于存储和...在实际项目中,根据需求和环境选择合适的编码策略,是保证软件国际化和本地化的重要步骤。

    QT国际化中文

    "QT国际化中文"通常涉及到的问题是,在非UTF-8编码环境下,中文字符可能出现乱码,这是因为程序没有正确处理字符编码或者未适配多语言环境。 在QT中,处理国际化主要涉及以下几个步骤和工具: 1. **linguist.exe**...

    Qt国际化教程

    Qt作为一个广泛使用的跨平台应用程序框架,提供了强大的国际化(i18n)支持,使得开发者能够轻松地为其应用程序添加多语言功能。本文将深入探讨Qt的国际化教程,包括创建翻译文件、使用QTLinguist工具以及如何在应用...

    QT中文国际化使用方法

    QT作为一个广泛应用于跨平台应用程序开发的框架,提供了强大的国际化支持。本文将详细介绍如何在QT项目中实现中文国际化的步骤,并解决在开发过程中遇到的乱码问题。 #### 二、准备工作 进行QT中文国际化之前,需要...

    Qt样式表+QML+乱码说明文档

    综上所述,Qt提供了一套完整的工具链,从Qt StyleSheet进行UI定制,到QML进行富界面设计,再到处理各种编码问题,以确保程序的国际化和用户体验。通过深入理解和熟练应用这些技术,开发者可以构建出美观、功能强大的...

    05 QString字符串处理及中文乱码问题处理.zip

    7. 国际化(i18n):Qt提供QTranslator和QApplication::translate等工具实现国际化,需要特别注意字符串资源的编码问题。 通过学习这一部分,开发者不仅可以掌握QString的基本用法,还能理解如何在Qt环境下有效地...

    Qt可用的一些中文字库

    6. **本地化与国际化**:对于支持多语言的应用,Qt的QLocale和QTranslator类可以帮助进行本地化,而QFontMetrics和QTextLayout可以辅助进行文本布局和换行处理。 7. **性能优化**:大量使用自定义字体可能会影响...

    总结QT4中文显示问题

    3. **国际化与本地化**:对于需要支持多语言的应用程序,应该考虑使用QT提供的国际化和本地化功能,例如`.ts`文件和`.qm`文件。这样可以更加灵活地管理不同语言的文本资源。 ### 四、常见问题及解决方案 #### 1. ...

    Qt中文显示

    在Ubuntu Linux环境下,由于其默认编码可能与Qt的默认编码不同,因此可能会遇到中文显示乱码的问题。本文将详细介绍如何在Qt 4.6.2版本中正确地实现中文显示。 首先,理解Qt的国际化(i18n,Internationalization)...

    Qt 国际化及 Qt Linguist 的使用

    Qt 国际化及 Qt Linguist 的使用 Qt 国际化及 Qt Linguist 的使用是 Qt 应用程序中非常重要的一部分。国际化是指使应用程序能够适应不同语言和文化环境的能力,而 Qt Linguist 则是 Qt 提供的一种强大的多国语言...

    基于QT的中英文翻译动态切换

    此外,为了实现更复杂的翻译功能,比如从外部资源加载翻译字符串,你可以使用Qt的国际化支持,如`.qm`文件。`.qm`文件是由Qt Linguist工具生成的,包含了不同语言的翻译数据。在QML中,可以使用`Qt.createQmlObject`...

    qt实现右击鼠标弹出菜单

    确保你的Qt项目设置支持UTF-8编码,同时确保所有字符串都通过`tr()`函数进行处理,以利用Qt的国际化机制。如果问题仍然存在,检查你的.pro文件,确保包含以下行: ```cpp QT += core gui widgets CONFIG += c++11 ...

    http文件服务器 多线程 并发处理

    然而,它还有待改进,如解决中文文件名的乱码问题和扩展对非英文文件名的支持,以增加其适用性和国际化程度。对于开发者来说,这是一个很好的学习和实践多线程、并发处理以及HTTP服务器开发的机会。

    QT制作的登录界面,简简单单

    在标签中提到"无乱码"再次强调了界面的中文显示正常,这是一个对中文用户非常重要的特性,尤其是在国际化的软件开发中。 压缩文件名为"QTLogin",很可能包含了项目的源代码文件,比如`.cpp`和`.h`文件,这些文件...

    Qt 编写多窗口程序 (2).pdf

    6. **资源管理与国际化支持** - 提及使用Qt的资源系统管理应用程序中的图片、图标等非文本资源,以及如何使用`.qm`文件实现程序的国际化。 7. **布局管理** - 简述如何使用Qt的布局管理器(如`QVBoxLayout`、`...

    qlabel加载图像,并支持单击事件,提出中文提示

    `tr()`函数在这里用于进行字符串的国际化处理,使得程序支持多语言,包括中文。`QMessageBox::information()`则用于弹出一个带有指定标题和消息的对话框。 现在,关于标签中提到的“QT4”和“中文提示”,在QT4中,...

    UTF-8与GB2312文件编码转换(支持批量文件)

    4. `Qt5Core.dll` - Qt的核心库,包含了事件处理、线程管理、国际化等功能。 5. `D3Dcompiler_47.dll` - DirectX的编译器,用于将着色器源代码编译为可执行的图形指令。 6. `libGLESV2.dll` - OpenGL ES 2.0的实现,...

    批量转 GBK 转 UTF-8 gb2312 Iso-8959-1 转 UTF-8

    3. 国际化项目:在开发多语言软件时,使用UTF-8可以支持各种语言,避免编码冲突。 总的来说,理解和掌握各种字符编码对于IT从业者来说至关重要,特别是在处理跨语言数据和系统集成时。同时,了解如何进行编码转换,...

    为了适应不同语言资源

    这涉及到软件本地化、国际化以及多语言支持等多个方面。以下是一些关键的知识点: 1. **软件本地化**(Software Localization):这是为了让软件能够适应特定地区的文化和语言需求,包括界面翻译、日期/时间格式、...

    GUI.Design.Studio2.0.47

    5. **国际化与本地化**:对于存在多语言需求的软件,需要考虑如何设计支持不同语言的界面,防止出现如中文乱码等问题。 6. **响应式设计**:随着移动设备的普及,一个优秀的GUI设计应能适应不同的设备和屏幕大小,...

Global site tag (gtag.js) - Google Analytics