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 已经换成中文的 "中文输入" 了.
浅谈Linux 下的中文程序开发(3)
内容版权声明:除非注明,否则皆为本站原创文章。