linux中文的编程,浅谈Linux 下的中文程序开发

浅谈Linux 下的中文程序开发

[日期:2007-08-05]

来源:Linux公社

作者:Linuxidc

[字体:大 中 小]

gtk_container_border_width(GTK_CONTAINER(window),10); 定义了我们的主窗口的 border(边缘)宽度为 10.

vbox = gtk_vbox_new (FALSE, 0); 定义了一个新的 gtk_vbox 出来.用来排列我们放在主窗口中的对象.

gtk_container_add (GTK_CONTAINER (window), vbox); 就把 vbox 通过 gtk_container_add 加入到我们的主窗口 window 中.

gtk_widget_show(vbox); 通过呼叫 gtk_widget_show 在主窗口中显示我们的 vbox

label= gtk_label_new("Input Line"); 通过 gtk_label_new 定义一个 label,而这个 label 显示的内容为 "Input Line"

gtk_box_pack_start(GTK_BOX (vbox), label, TRUE, TRUE, 0); 是通过 gtk_box_pack_start 把 label 放到我们前面生成的 vbox 中.

gtk_widget_show(label); 再次利用 gtk_widget_show, 这次是在 vbox 中显示我们新加入的 label.

entry = gtk_entry_new(); 用 gtk_entry_new 定义了一个 entry. 这里就是指产生一个可以接受文字输入的对象,就好像 QT 中的 LineEdit 一样.

gtk_signal_connect(GTK_OBJECT(entry), "activate", GTK_SIGNAL_FUNC(display), entry); 这里,我们连接一个 gtk 信号,信号作用于 entry,也就是我们前面产生的那个文字输入对象.当我程序接收到 "activate" 这个信号的时侯,就去呼叫 display() 这个 function, 同时把 entry 传给 display(). 这里的 activate 信号,就是当我们按下键盘的 enter 键时所产生的. gtk 当适用者按下 enter 键的时侯,就会送初一个 activate 的信号.所以当我们输入一些文字以后,按下 enter 键,这些文字就会被送到 display() 去处理了.

gtk_box_pack_start(GTK_BOX (vbox), entry, TRUE, TRUE, 0); 再次用 gtk_box_pack_start 把对象 entry 加入到 vbox 中.

gtk_widget_show(entry); 显示 vbox 中的对象 entry

gtk_widget_show(window);

gtk_main();

最后我们显示我们的主窗口.并且进入 gtk 的 main loop.

Tips: 这里我们利用 gtk_widget_show() 先显示了 window 中的 vbox, label, entry, 最后才去显示主窗口 window 是因为这样的话,当主窗口 window 显示出来的时侯. vbox, label, entry 已经比 window 先显示好了.这样我们看到的 就是一个整体的 window. 有主窗口,有 label 和 entry. vbox, label, entry 都是在主窗口显示以前就已经画好的了. 所以主窗口一出来,不用等待 label, entry 的出现. 如果先去显示 window, 再去显示 vbox, label, entry, 那么在比较慢的计算机上面(或者你的程序比较复杂的情况下) 你将会先看到一个空白的主窗口出现,然后再慢慢的画出 label 和 entry 来.

现在来看一下我们的 Makefile

代码:

INCL= -I/usr/lib/glib/include/ -I/usr/include/gtk-1.2/gdk/ -I/usr/include/gtk-1.2/ \

-I/usr/include/glib-1.2/

LIBS= -L/usr/X11R6/lib

LFLAGS= -lglib -lgdk -lgtk -lX11 -lXext -lm

CC=gcc

chinese: chinese.c

$(CC) $(INCL) -o chinese chinese.c $(LIBS) $(LFLAGS)

clean:

rm -f chinese

rm -f *.bak

.SUFFIXES: .c

.c.o:

$(CC) -c $(CFLAGS) $(INCL) -o $@ $<

写 好 Makefile 以后. make 一下,就可以编译出 GTK+ 版的 chinese 了.执行以后, 我们可以发现,在可以输入文字的地方,直接输入中文,就可以在 X 终端模拟中正确的显示出来中文. 所以我们需要的,就只有把接口中文化一下就好了. 中文化 gtk+ 程序的时侯,会比 QT 稍稍麻烦些.

代码:

#include

#include

#include

#include

#define PACKAGE "chinese"

#define LOCALEDIR "/home/goldencat/program/gtk/chinese/final"

#define _(STRING) gettext(STRING)

void display(GtkWidget *widget, GtkWidget * entry)

{

const gchar *entry_text;

entry_text=gtk_entry_get_text( GTK_ENTRY (entry));

printf ("%s\n", entry_text);

}

void destroy(GtkWidget *widget, gpointer *data)

{

gtk_main_quit();

}

int main(int argc, char *argv[])

{

GtkWidget *window;

GtkWidget *vbox;

GtkWidget *entry;

GtkWidget *label;

gtk_set_locale();

bindtextdomain (PACKAGE, LOCALEDIR);

textdomain (PACKAGE);

gtk_init(&argc, &argv);

window=gtk_window_new(GTK_WINDOW_TOPLEVEL);

gtk_signal_connect(GTK_OBJECT(window), "destroy", GTK_SIGNAL_FUNC(destroy),NULL);

gtk_container_border_width(GTK_CONTAINER(window),10);

vbox = gtk_vbox_new (FALSE, 0);

gtk_container_add (GTK_CONTAINER (window), vbox);

gtk_widget_show(vbox);

label= gtk_label_new(_("Input Line"));

gtk_box_pack_start(GTK_BOX (vbox), label, TRUE, TRUE, 0);

gtk_widget_show(label);

entry= gtk_entry_new();

gtk_signal_connect(GTK_OBJECT(entry), "activate",

GTK_SIGNAL_FUNC(display), entry);

gtk_box_pack_start(GTK_BOX (vbox), entry, TRUE, TRUE, 0);

gtk_widget_show(entry);

gtk_widget_show(window);

gtk_main();

return 0;

}

首 先我们需要 locale.h 和 libintl.h 然后还要定义 PACKAGE, LOCALEDIR 这里的 PACKAGE 就是我们翻译后的 mo 文件的名称. 这里把它定义为 chinese 因为我们的程序就叫做 chinese, GTK+ 会在固定的地方寻找 mo 文件.在 RedHat 7.3 中,会在 /usr/share/locale/你的locale/LC_MESSAGES 下面寻找 mo 文件. 对于中文来说,也就是 /usr/share/locale/ 下面的 zh_TW zh_TW.Big5 zh_CN zh_CN.GB2312 这几个目录中的 LC_MESSAGES 下面.去寻找 mo 文件.

这里我们去定义 LOCALEDIR 就是告诉 gtk+ 我们希望 gtk+ 到哪里去寻找 mo 文件. /home/goldencat/program/gtk/chinese/final 就是 chinese.c 的位置.也就是我们的当前工作目录.这样 gtk+ 就不会再去 /usr/share/locale/ 下面找相应语言环境中的 LC_MESSAGES 中寻找 mo 文件了. 而是在您 LOCALEDIR 中定义的位置.(配合 bindtextdomain 使用)

而 后面的 #define _(STRING) gettext(STRING) 只是说把 gettext(STRING)换成 _(STRING) gettext 就好像前面 QT 中的那个 tr 一样.在产生 po 文件的时侯,就是根据 gettext 来决定哪些信息是需要翻译的.只不过每个需要翻译的信息都把 ("English String") 改成 (gettext("English String")) 未免有些麻烦.所以 GTK+ 中,大家都把 gettext(STRING) 换成 _(STRING), 这样我们就只需要 (_("English String") 就可以了.

Tips: 如果您在您的计算机中编译这些东西,请记得把 #define LOCALEDIR "/home/goldencat/program/gtk/chinese/final" 改换成您自己的工作目录

在 gtk_init() 之前,我们需要告诉 gtk 我们有翻译的信息.所以要有下面三个动作:

gtk_set_locale();

bindtextdomain (PACKAGE, LOCALEDIR);

textdomain (PACKAGE);

get_set_locale() 告诉 gtk 去找我们现在用的 locale (QT 中的 TextCodec::locale())这样 gtk+ 就会自动判断出当前 locale 的环境,然后去相应的环境下面找 mo 文件.

bindtextdomain() 则是告诉 gtk 去哪里找 mo 文件. 这里我们要它去我们定义的 LOCALEDIR 下面找 PACKAGE (chinese)

textdomain() 就是载入翻译的信息啦.

最后就是把 label= gtk_label_new("Input Line"); 改成 label= gtk_label_new(_("Input Line")); 这样 xgettext 就可以找到需要翻译的信息了.

现在我们就算是完成了程序这边对中文化的支持了. gtk+ 需要用 xgettext 来产生 po 文件的.所以我们用:

xgettext -k_ chinese.c -o chinese.po

这里的 -k_ 就是说 keywork 是 _ ,也就是说 xgettext 会去找程序中的 _(STRING) 出来. 现在打开 chinese.po 看看:

代码:

# SOME DESCRIPTIVE TITLE.

# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER

# This file is distributed under the same license as the PACKAGE package.

# FIRST AUTHOR , YEAR.

#

#, fuzzy

msgid ""

msgstr ""

"Project-Id-Version: PACKAGE VERSION\n"

"POT-Creation-Date: 2002-06-23 17:44-0400\n"

"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"

"Last-Translator: FULL NAME \n"

"Language-Team: LANGUAGE \n"

"MIME-Version: 1.0\n"

"Content-Type: text/plain; charset=CHARSET\n"

"Content-Transfer-Encoding: 8bit\n"

#: chinese.c:38

msgid "Input Line"

msgstr ""

跟翻译 QT 的 po 一样,我们真正需要动到的只有 charset 和 msgstr "

" 而已.当然,您也可以加入相应的翻译信息,

PO-Revision-Date: 翻译时间

"Last-Translator: 翻译人 翻译人_E-Mail地址

Language-Team: 翻译团队 翻译团队_E-Mail_地址

下面是翻译好的 po

代码:

# SOME DESCRIPTIVE TITLE.

# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER

# This file is distributed under the same license as the PACKAGE package.

# FIRST AUTHOR , YEAR.

#

#, fuzzy

msgid ""

msgstr ""

"Project-Id-Version: PACKAGE VERSION\n"

"POT-Creation-Date: 2002-06-23 17:44-0400\n"

"PO-Revision-Date: 2002-06-23 14:45-0400\n"

"Last-Translator: Goldencat &l;ruili@worldnet.att.net>\n"

"Language-Team: LANGUAGE &l;ruili@worldnet.att.net>\n"

"MIME-Version: 1.0\n"

"Content-Type: text/plain; charset=Big5\n"

"Content-Transfer-Encoding: 8bit\n"

#: chinese.c:38

msgid "Input Line"

msgstr "中文输入"

存档以后.我们用:

msgfmt -o chinese.mo chinese.po

生成 mo 文件.

跟 QT 不同的是, GTK+ 不是通过判断 mo 名子来载入不同的的 mo 的. 在 GTK+ 下面.任何 locale (语言环境)的 mo 名子都叫做 chinese.mo 那么 GTK+ 是如何分辨不同的 locale 需要加载相对语言的 mo 呢? GTK+ 是通过把不同的 mo 放在不同的目录下,然后通过判断目录名称来找到相应的 mo 文件的. 所以存放 GTK+ mo 文件的目录名,需要跟相应的 locale 一致. GTK+ 就会在这个目录下的 LC_MESSAGES 中找到所需要的 mo 文件了. 所以我们首先需要在当前目录下做出相应的存放 mo 文件的目录.

$mkdir zh_TW

$mkdir zh_TW/LC_MESSAGES

$cp -r zh_TW zh_TW.Big5

$cp -r zh_TW zh_CN

$cp -r zh_TW zh_CN.GB2312

这样我们就有了中文所需要的四个最基本的目录了. 现在我们把 chinese.mo 放到相应的目录下面

$cp chinese.mo zh_TW/LC_MESSAGES

$cp chinese.mo zh_TW.Big5/LC_MESSAGES

然后在做一份 GB2312 的 mo 放在 zh_CN 和 zh_CN.GB2312

实 际上,在 RedHat7.3 中, export LANG=zh_TW.Big5 情况下(LC_MESSAGES=zh_TW.Big5)GTK+ 会在 zh_TW/LC_MESSAGES 下面寻找 mo 文件. 而 export LANG=zh_CN.GB2312 的情况下(LC_MESSAGES=zh_CN.GB2312)GTK+ 则是在 zh_CN.GB2312/ LC_MESSAGES 下面寻找 mo 文件.

现在试试在不同的 locale 运行一下 ./chinese 您会看到, 程序已经被中文化了.那个 Input Line 已经换成中文的 "中文输入" 了. 0b1331709591d260c1c78e86d0c51c18.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值