一:字符集介绍
我国已经颁布了多种中文信息编码标准,常用的有:GB2312-1980、GB12345、GB13000(GBK)以及最新标准GB18030,其中GB13000是对GB2312的扩展,又常被成为GBK,GB18030向下兼容GB2312和GBK,中文WINDOW98、中文WIN2000操作系统采用的中文字符集是GB2312。
GB2312字库仅覆盖双字节部分,存储位置索引是编码中每字节的第8bit置0得来的,如A1A1编码汉字在字库中的索引是2121,而非A1A1。以下是它的编码规则:
单字节:00~7F
双字节:A1~F7 A1~FE
GBK的编码规则是:
单字节:00~7F
双字节:81~FE 40~7E
80~FE
GB18030是最新的汉字编码标准,其编码为一、二、四变长编码:
单字节:00~7F
双字节:81~FE 40~7E
80~FE
四字节:81~FE 30~39 81~FE 30~39
Unicode编码采用等长编码,二个字节表示一个字符编码,对于ASCII码也采用双字节来表示,unicode使用二维空间来描述编码空间,平面分为256行、256列,对应于编码的高低字节。
二:Qt 国际化编程
在文本显示上,Qt 使用了Unicode 作为内部编码,为了程序的国际化,通常我们在文本显示的地方不直接输入本地字符,用英文代替,比如要编写一中文界面的 Qt 程序,应该在程序中使用英文,程序编写完成后,把文本提取出来翻译。对于需要翻译的地方,首先是在该文本处用tr()函数标识,同时制作出.qm信息文件,并在程序中加入QTranslator即可。比如我们在某一程序中有如下语句:
setCaption(tr(“main window”));
为了能显示中文,有两种方法:
方法一:
1 修改工程文件,加上TRANSLATIONS = xxx.ts
2 lupdate 工程文件名
3 用linguist编辑刚生成的xxx.ts文件并保存
4 lrelease 工程文件名 xxx.qm
5 在main.cpp中加入:
#include <qfont.h>
#include <qtranslator.h>
QFont font1("unifont",16,50,FALSE,QFont::Unicode);
qApp->setFont(font1);
QTranslator *translator = new QTranslator(0);
translator->load("xxx.qm", ".");
qApp->installTranslator(translator);
方法二:
1 findtr 文件名(通常为CPP文件) > xxx.po
2 编辑po文件,其中charset需由iso-8859-1改为GB2312,然后将“main window”翻译成“主窗口”
3 msg2qm –scope zh_CN.GB2312 xxx.po xxx.qm
4 在main.cpp中加入:
QFont font1(“unifont”,16,50,FALSE,QFont::Unicode);
qApp->setFont(font1);
QTranslator *translator = new QTranslator(0);
translator->load("xxx.qm", ".");
qApp->installTranslator(translator);
方法三:
有时我们只是提供给本地用户使用,无需国际化,QT提供这一支持,在QT中有许多本地字符集同unicode的转换引擎,他们皆为QTextCodec的派生类,如QGbkCodec、QJisCodec, QHebrewCodec等。如:
QFont font1(“unifont”,16,50,FALSE,QFont::Unicode);
qApp->setFont(font1);
QString caption=“主窗口“;
QTextCodec *gk_codec=QTextCodec::codecForName(“GBK”);
setCaption(gk_codec->toUnicode(caption));
从上面可以看出,使用转换引擎可以轻松实现中文显示,简要步骤如下:
1:修改main.cpp文件,将字体改为unifont
QFont font1(“unifont”,16,50,FALSE,QFont::Unicode);
qApp->setFont(font1);
2:在想汉化的内的头文件中加入QTextCodec指针变量和转换函数QString mytr(char *)
#include <qtextcodec.h>
QTextCodec* gbk;
QString mytr(const char *);
3:在想汉化的类的实现文件中,修改类构造函数,加入:
gbk=QTextCodec::codecForName(“GBK”);
4:在想汉化的类的实现文件中,添加mytr函数代码
QString Form1::mytr(const char* chars)
{
return gbk->toUnicode(chars,strlen(chars));
}
5:在想汉化的类的实现文件中,用“mytr”替换“tr”
2004-12-2 测试了上面的方法三,编译通过,如果将codec成员变量改成QTextCodec派生类变量,编译将通不过,比如将QTextCodec* gbk;改成QGbkCodec* gbk;编译将报告此处有语法错误。下面是相似的用法:
1:修改***.cpp文件,在顶部加入codec头文件
#include <qgbkcodec.h>
2:在***.h文件中,加入mytr()函数声明
QString mytr(char* buffer,int size);
3:在***.cpp文件中,加入mytr()定义
QString mytr(char* buffer,int size)
{
QGbkCodec* gbk=QTextCodec::codeForName("GBK");
return gbk->toUnicode(buffer,size);
}
4:在需要显示中文的地方,使用mytr函数即可
5:修改main.cpp文件,将字体改为unifont
QFont font1("unifont",16,50,FALSE,QFont::Unicode);
qApp->setFont(font1);
备注:在翻译或转换之前必须将Unicode字体调入,否则显示不出中文,网上相关文章并未提及这一点,如果不显式装载该字体,系统默认的是Latin1,于是汉字显不出来。
备注2:在编译qt/embedded之前,必须修改qconfig-qpe.h配置文件的内容,将与TextCodec相关的宏定义给去掉,否则QTextCodec::codecForName(“GBK”)将返回NULL指针。
备注3:使用findtr命令时可同时查找多个文件的tr(),并将查找结果都放入一个文件内,源文件以空格隔开即可,另外,生成的.po和.qm文件的文件名最好与工程文件名相同!
备注4:如果要显示繁体中文,则需要使用QTextCodec::codecForName(“big5”)。获取本地的使用语言,用QTextCodec::locale(),它返回Qstring变量,通常如果是中文本地的话,通常其值为zh_CN.GB2312和zh_TW.Big5,根据这个返回字符串,可以加载相应的codec。如果程序只支持一种编码,也可以直接把整个应用程序的编码设置为一个默认的编码标准,比如系统只需要显示中文和英文,则可以直接设置应用程序的默认编码标准是GBK,如下使用方法:
qApp->setDefaultCodec( QTextCodec::codecForName("GBK") );
QLabel *label = new QLabel( tr("中文标签") );
备注5:如果使用本地的字符转换器,可以使用Qstring的静态函数Qstring::fromLocal8Bit(char* buffer,int size),将本地字符串转换成UNICODE字符串,不过要设置好LANGUAGE环境变量。
三:QTOpia中文化
1 findtr 文件名 > xxx.po
2 编辑xxx.po文件
3 msg2qm –scope zh_CN.GB2312 xxx.po xxx.qm
4 拷贝可执行文件到QPEDIR/bin目录
5 拷贝xxx.po和xxx.qm文件到QPEDIR/i18n/zh_CN目录
6 进入QPEDIR/apps/Applications目录创建一新.desktop文件
7 iconv –f utf8 –t GB18030 xxx.desktop > xxx1.desktop
8 编辑xxx1.desktop文件,主要是修改Exec、Icon、Name和Name[zh_CN]四项
9 iconv –f GB18030 –t utf8 xxx1.desktop > xxx.desktop
10 rm –f xxx1.desktop
11 qvfb –depth 16 &
12 cd $QPEDIR/bin
13 ./qpe
备注:如果你的系统中有多个qtopia版本,要特别注意QTDIR、QPEDIR、LD_LIBRARY_PATH环境变量
备注2:可按照此方法汉化qtopia自带的应用程序
备注3:po文件是中间文件,程序真正需要的是qm文件。iconv是系统自带的内码转换工具,它能将utf8编码的文件转换成gb18030编码的文件,反之也能,转换这一步必不可少,因为desktop文件缺省是utf8编码的,而我们的redhat linux 7。3中文操作系统用的却是gb18030,所以在编辑器打开前需转换。
四:汉化qtopia-1.5.0 for Arm
首先按照“三”的方法对要汉化的程序提取*.qm文件和*.desktop桌面配置文件,在做完这一步后,将*.qm文件down到目标机的/opt/qtopia-free-1.5.0.arm/i18n/zh_CN目录下,同时将*.desktop文件覆盖/opt/qtopia-free-1.5.0.arm/apps目录下的相应文件,目标机的环境变量配置如下:
export QTDIR=/opt/qt-2.3.3.arm
export QPEDIR=/opt/qtopia-free-1.5.0.arm
export LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH
export PATH=$QPEDIR/bin:$PATH
export LANG=zh_CN
开机启动,由于设置的语言为简体中文,qpe会自动为每个应用加载Unifont字体,以及简体中文目录下的翻译文件,因而显示出中文,翻译文件是一个方面,但更关键的是要显示中文必须有中文字体来支持,Unifont字体包含中文字,因而能显示中文,没有相应字体的支持,光有翻译文件是显示不出中文的!
在经过以上的步骤后,有的应用在显示上依然会显示方框,这多半是由于该窗体相关的字体可能不是支持中文的字体,这需要直接修改源代码,以下是在汉化qtopia-free-1.5.0.arm的过程中的相关记录:
1. 在编译qtopia的过程中,可能会报告找不到SetButtonGroupID()函数,编译通不过。这是由于库中并没有该函数,一般情况下将该语句隐藏掉,原代码的原意是设置Button按钮在ButtonGroup组的序号,隐藏该语句对应用无影响。出现这个问题,主要在/netsetup/dialup/dialupbase.cpp文件和/taskbar/shutdown.cpp文件,shutdown.cpp文件的相应行号是:96、149、201、253行。
2. 修改mpegplayer/playlistwidget.cpp文件的143行和166行,将字体设置改为Unifont,如下:Qfont(“unifont”,16,50,FALSE,QFont::Unicode)或者去掉该语句
3. 修改snake/interface.cpp的87行和186行,将字体设置改为Unifont,如下:Qfont(“unifont”,16,50,FALSE,QFont::Unicode)或者去掉该语句
4. 修改qasteroids/view.cpp的104行和qasteroids/toplevel.cpp的109行和165行,将字体设置改为Unifont,如下:Qfont(“unifont”,16,50,FALSE,QFont::Unicode)或者去掉该语句
5. 修改sysinfo/versioninfo.cpp文件,将61行的builder改为作者本人,将50行的v改为tr(“corpname”),重新建立po文件,并翻译corpname为国营789北京开发部,使用msg2qm生成qm文件
6. 修改桌面,位于taskbar目录下,生成libqpe.po和libqpe.qm文件,并将libqpe.qm文件拷贝到i18n/zh_CN目录下
五:qtopia目录结构
apps/Applications:应用程序桌面配置文件
apps/Games:游戏桌面配置文件
apps/Settings:系统设置桌面配置文件
bin:二进制可执行文件
configs:编译配置文件目录
doc和docs:qtopia的参考文档
etc:应用配置文件目录
i18n:国际化目录
i18n/zh_CN:简体中文目录
include/qpe:与qtopia相关的头文件目录
inputmethods:输入法
library:qtopia部分源代码目录
pics:与应用相关的图片存放目录
plugins:各种插件目录,如mpeg3解码插件、输入法插件等
sounds:音频文件存放目录
taskbar:桌面程序的源代码(qpe的源代码)