发新话题
打印

[转贴] 让linux变成中文版(一)

让linux变成中文版(一)

本文网址:http://bbs.bitscn.com/118055 复制

免费内容:
现在越来越多的华人开始用 Linux 了.也越来越多的华人开始写我门自己的 Linux 下面的应用程序了. 开发我门自己的程序,中文当然是一个必不可少的东西了. 这里就来说说 Linux 下面的中文程序的开发. 小弟才疏学浅,只是因为看到网络上面这方面的文章不是很多很全面.所以动手写了这些东西.如果有错误,还望大家多多包含,多多指正.

QT
QT 现在被越来越多的人所喜爱.也有了越来越多的人选择 QT 作为开发Xwindow 下面 GUI 环境的语言. 在 Linux 中,绚丽的 KDE 桌面环境就是用 QT 开发出来的. 现在来看看如何在 QT 下面处理中文.
本文中全部在 QT 3 的环境下运作.如果您用的是比较旧的 QT 版本, 请注意:
Tips: 如果您的 Linux 系统中找不到 findtr3 那么请尝试找 findtr2 或者 findtr
Tips: 如果您的 Linux 系统中找不到 msg2qm2 那么请尝试找 msg2qm
Tips: 可以用 which findtr3 或者 whereis msg2qm2 来寻找您的系统
Tips: 如果您希望在自己的计算机中编译本文中的范例, 您需要安装 g++, qt, qt-devel, make 这些 套件.
下面我们来看一个简单的 QT 程序:
代码:
/* chinese.h */

#include
#include
#include
#include

class Chinese: public QWidget
{
Q_OBJECT
public:
Chinese();
private:
QLabel *label;
QLineEdit *input;
private slots:
void display();

};



这里我们简单的定义了一个基于 QWidget 的 class, 命名为 Chinese 然后我们定义了一个 Label *label 和一个 LineEdit input 并且定义一个 代码:
void slot display()
/* chinese.cpp */

#include "chinese.moc"
#include

Chinese::Chinese()
{
resize(200,100);

label=new QLabel( "Input Line:", this);
label->setGeometry(10,10,90,30);

input=new QLineEdit(this);
input->setGeometry(10, 40, 180, 30);
input->setFocus();
connect(input, SIGNAL(returnPressed()), this, SLOT(display()));

}
void Chinese::display()
{
QCString string;
string=input->text();
cout<<STRING<
}



在 .cpp 文件中. Chinese::Chinese() 中,我们只做了四件最简单的事情 1. 显示一个叫做 Input Line: 的 label 在 10,10 这个位置上. 大小为 90 30. 然后显示一个可以用来输入的 LineEdit 在 10, 40, 大小为 180, 30. 然后告诉程序,当程序打开的时侯,将 focus 用 setFocus() 放在 input ( QLineEdit )上面.也就是说,程序一打开,我们打 keyboard 就可以直接输入到 input 这个 QLineEdit 中. 然后我们告诉程序,当在 input 中接收到 Enter 键的时侯,去呼叫 display() 这个 slot Chinese::display() 中.我们有三个动作. 1. 定义一个 QCString 用作 QT 与 C++ 之间的沟通. string=input-text() 把我们输入在 input 中的 string 抓下来,放到 string 中.然后用 cout 把 string 显示在您的 X 终端模拟中. (rxvt, qterm, xter Konsole 之类的程序)

代码:
/* main.cpp */

#include
#include "chinese.h"

main (int argc, char **argv)
{
QApplication a(argc, argv);
Chinese w;
a.setMainWidget (&w);
w.show();
return a.exec();
}



这个就不多说了.是 chinese 的 main 程序.用来显示 chinese 的.

然后建立一个如下的 Makefile:
代码:
INCL= -I$(QTDIR)/include -I/usr/include/kde
CFLAGS= -pipe -O2 -fno-strength-reduce
LFLAGS= -L$(QTDIR)/lib -L$(KDEDIR)/lib -L/usr/X11R6/lib
LIBS= -lkdecore -lkdeui -lqt -lX11 -lXext -ldl
CC=g++
MOC=moc

chinese: chinese.moc chinese.o main.o
$(CC) $(LFLAGS) -o chinese chinese.o main.o $(LIBS)
chinese.moc: chinese.h
$(MOC) chinese.h -o chinese.moc
main.o: main.cpp
chinese.o: chinese.cpp

clean:
rm -f *.o
rm -f *.bak
rm -f *.moc
rm -f chinese

.SUFFIXES: .cpp .h

.cpp.o:
$(CC) -c $(CFLAGS) $(INCL) -o $@ $<



通 过 make 指令.我们就可以 build 出一个可执行的文件 chinese 执行 ./chinese 可以看到我们的小程序. 我们在程序中那个可以输入的地方,随便打些东西进去(请输入英文)然后按 enter 键. 我们就会看到我们在程序中输入的那些东西会被显示在我们的 X 终端模拟中.

但是目前这个程序既不能显示中文,同样的也不能接受中文输入. 不相信的话,您可以尝试在那个输入文字的地方打入随便几个中文. 例如 "中文测试" 然后按 Enter 键.您会发现 X 终端模拟中显示的只有 "??" 之类的东西. 原因后面会讲到.

首先,我们第一部需要的是让我门的程序显示中文.相信大家一定都知道, QT 中已经帮我们做好了 i18n 了.只要去用就好. 首先我们需要在 chinese.h 的文件中加入:
#include qtranslator.h 是给 QTranslator 用的 include 文件. 然后在 chinese.cpp 中 Chinese::Chinese 需要改成下面的样子:
代码:
Chinese::Chinese()
{
resize(200,100);
QTranslator translator(this);
translator.load("chinese", ".");
qApp->installTranslator(&translator);

label=new QLabel(tr( "Input Line:"), this);
label->setGeometry(10,10,90,30);

input=new QLineEdit(this);
input->setGeometry(10, 40, 180, 30);
input->setFocus();
connect(input, SIGNAL(returnPressed()), this, SLOT(display()));

}



首 先,我们定义了 QTranslator translator 在 this. 然后 translator.load 去载入 chinese.qm 这个文件.这里 .qm 这个全名称我们是不需要的. QT default 就会去找 .qm 了. 所以虽然我们的中文对应的翻译文件全名是 chinese.qm ,但是我们这里只需要打入 chinese 就好了.

qApp->installlTranslator(&translator)就会帮我们把翻译成中文的信息, 加载我们的程序中.

同 时, label=new QLabel("Input Line:", this) 要改成下面这样 label=new QLabel(tr( "Input Line:"), this) 这里的 tr 是代表信息需要翻译 (translator)的意思. tr 也是给 findtr 来寻找哪里需要信息翻译的一个标志 (flag)

现在用 make 重新编译我们的程序. 编译完后,我们还需要做出 qm 文件来给 QTranslator 用.

首先,我们需要用到 findtr3 这个程序. findtr3 会帮我们找出程序中所有用到 tr 的地方.同时帮我们自动产生 po 文件.
findtr3 chinese.cpp > chinese.po
现在用您最喜爱的文字编辑器(vim, emacs, joe or other)打开 chinese.po 这个文件,我们会看到:
代码:
# This is a Qt message file in .po format. Each msgid starts with
# a scope. This scope should *NOT* be translated - eg
# from French to English, "Foo::Bar" would be translated to "Pub",
# not "Foo::Pub".
msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"POT-Creation-Date: 2002-06-22 20时09分00秒 EDT\n"
"PO-Revision-Date: YYYY-MM-DD\n"
"Last-Translator: FULLNAME \n"
"Content-Type: text/plain; charset=iso-8859-1\n"

#: chinese.cpp:15
msgid "Chinese::Input Line:"
msgstr ""



这 里 findtr3 帮我们找到,在 chinese.cpp 这个程序中的第 11 行,有一处用到 tr 的地方. 而 tr 后面的内容是 Input Line: 还记得我们的 label 是怎么写的吗? label=new QLabel(tr( "Input Line:"), this); 没错, 这里找到的就是 "Input Line:" 这几个字. 下面我们开始翻译 po 文件了

我们真正需要动到的只有两个地方,就是:
"Content-Type: text/plain; charset=iso-8859-1\n"
和下面的 msgstr "" 就足够了.

代码:

#: chinese.cpp:15
msgid "Chinese::Input Line:"
msgstr ""



首先我们需要设定我们是用哪种于言编码来翻译 po 的.同时 qt 也会用这种语言编码来显示我们所翻译的信息.所以我们需要改成:
代码:
"Content-Type: text/plain; charset=big5\n"

或者:
代码:
"Content-Type: text/plain; charset=gb2312\n"



其中 big5 是繁体中文所以用的编码, gb2312 (GBK) 则是简体中文所使用的.

接下来,我就需要更改 msgstr 了:
msgid "Chinese::Input Line:"
msgstr "请输入中文:"

Tips: 注意,如果您是用 gb2312 简体来输入的那么 您需要在 charset 中选择 gb2312. 同样的, big5 繁体输入,就需要选择 charset=big5 您不能用同一种编码的输入法,同时去写两 个 po 文件. 也就是说,不能用 xcin 的繁 体输入,同时去翻译 gb2312 的 po. 也不 能用 chinput 的简体输入来翻译 big5 的 po. 如果您需要同时翻译繁体,简体的 po 那么建议您用您所熟习的语言环境翻译好 一份出来,然后用 big5<=>gb 的转码工具 转出另外一个编码的po文件来.同时记得更 改所转出来的文件中的 charset
当然,如果您愿意,也可以把
"PO-Revision-Date: YYYY-MM-DD\n"
"Last-Translator: FULLNAME \n"
加入适当的信息
PO-Revision-Date: 加入您翻译的信息
Last-Translator: 加入您的个人信息以及 e-mail
"PO-Revision-Date: 2002-06-22\n"
"Last-Translator: Goldencat \n"


然后存盘,退出.先在我们还需要最后一步,就是把 chinese.po 文件转成 chinese.qm 的格式给程序来读.这时侯我们就用到了一只叫做 msg2qm2 的程序.
msg2qm2 chinese.po chinese.qm


现在我们就算是完成了. 执行我们的文件 ./chinese 看看,那个 "Input Line:" 已经变成中文的 "请输入中文:" 了.

下一步,我们来解决在 QT 中输入中文,然后把中文显示出来的问题.
Tips: QT 中的中文输入也很重要.写一个程序,不光是 表面上看起来信息都变成中文的,就叫做中文化 了.举一个最简单的例子:现在有一个中文的 MySql 数据库.我们的 QT 程序需要正确的输入 查询中文的数据.这就需要 QT 可以正确无误的 接受并且处理我们的中文输入才可以.
在 QT 中,我们有一个 QTextCodec 可以用. QTextCodec 就是专门来为我们处理不同编码的.

为了使用 QTextCodec 我们首先需要在 chinese.cpp 中,把 qtextcodec.h 给 include 进来.
include
现在来看看我们的 void Chinese::display() 吧.
代码:

void Chinese::display()
{
QString string;
string=input->text();
QTextCodec *codec=QTextCodec::codecForName("big5");
QCString chinese_string=codec->fromUnicode(string);
cout<<CHINESE_STRING<
}



这 里我们看到,同样的, 把 input 中我们输入的 string 扔给 string. 下面就用到了 QTextCodec 了.我们可以把 QTextCodec *codec=QTextCodec::codecForName("big5"); 写成两行,这样比较方便看:
代码:

QTextCodec *codec;
codec=QTextCodec::codecForName("big5");


第一行是通过 QTextCodec 建立 codec 第二行呢,告诉 QT 我们的 codec 是用 big5 编码的. (简体中文就要用 gb2312)

最 后,我们通过 codec->formUnicode(string) 把 Unicode 转换成我们需要用的 big5 码. ( QT default 全部是用 Unicode,这也就是为什么开始的时侯,如果我们没有通过 QTextCodec 转码,看到的中文都是 ?? 了.因为 Unicode 的标准就是不认得的 code 一律用 ?? 来表示)最后我们定义一个 QCString chinese_string,
代码:

QCString chinese_string=codec->fromUnicode(string);


而 chinese_string就是已经被 codec 转码过的 big5 code 的了. codec->fromUnicode(string) 这里是做转码的动作.

现在重新 make 所 build 出来的 chinese 就已经具备了最基本的中文程序的要求了.现在在输入中文到程序中,您就可以在 X 终端模拟中看到中文了.

那么这个程序已经具备了中文处理能力,为什么还被叫做最基本的呢中文处理呢?因为我们的程序目前并不会判断 locale, 而自动设定相应的编码.现在我们把这个 chinese 的程序作成一个相对完整的中文程序.

QTextCodec 中还给我们提供了一个读取当然于言环境的 function 叫做 locale. QTextCodec::locale() 就会返回当前使用者的 locale. 现在让我们来看看一个相对完整的中文程序:
Tips: 这个程序中对 locale 名称的定义 是按照 RedHat 7.3 中对中文 locale 的定义为标准的,也就是说: 繁体中文 : zh_TW.Big5 简体中文 : zh_CN.GB2312
代码:

/* chinese.h */

#include
#include
#include
#include
#include

class Chinese: public QWidget
{
Q_OBJECT
public:
Chinese();
private:
QLabel *label;
QLineEdit *input;
QString locale;
private slots:
void display();

};

郁闷
看见代码就头大

郁闷
看见代码就头大

不错,不过看不懂呀,计算机语言还得提高才能看懂,

大家认真学习就行了
刚刚学的时候都是这样子的

大学学的都忘光光

发新话题
版块跳转 
沪ICP备08026629号 / 管理员木木 / QQ58284700 / MSNjacro|at|bitscn.net / TEL13641763379 /