GTK1.2程序国际化步骤
有两种方法
第一种:使用gettext软件包
首先在源代码加入相关的头文件如下:
#include <libintl.h> //gettext支持
#include <locale.h> //locale支持
然后是定义宏,下面的定义形式在GNOME/GTK+中应用的标准格式:
#define _(string) gettext(string)
#define N_(string) string
在程序的主函数中加入下面相关函数:
//以下函数用来设定国际化翻译包所在位置
bindtextdomain(软件包名, locale所在目录);
如:bindtextdomain("hellogtk","/usr/share/locale/");
//以下函数用来设定国际化翻译包名称,省略了.mo
textdomain(软件包名);
如:textdomain("hellogtk");
相关的字符串修改
将代码中需要国际化--即多语言输出的字符串改写为_()宏,代码如下:
gtk_window_set_title (GTK_WINDOW(window), _("Hello Gtk!"));
……
label=gtk_label_new( _("Enter a message:") );
……
button=gtk_button_new_with_label (_("Print"));
生成相关文件与翻译
完成以上修改后,执行如下命令:
xgettext –a -o hellogtk.po hellogtk.c
它的功能是将hellogtk.c中的以下划线开始括号中(如宏定义所示)的字符串加入到hellogtk.po文件中。
修改hellogtk.po文件
po文件的头部可以加入软件包的名称、版本、翻译者的邮件地址等,po文件中以#开始的行为注释内容,以下为省略了头部的hellogtk.po文件内容,msgid后面的内容为英文,msgstr后面的内容为翻译的中文,翻译好后保存为UTF8格式。
注:系统i18n最好改为zh_CN.GB2312,不然翻译的msgstr会存不上。
vi hellogtk.po
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Type: text/plain; charset=zh_CN.GB2312\n"
#: hellogtk.c:45
msgid "Hello Gtk!"
msgstr "你好 Gtk!"
#: hellogtk.c:54
msgid "Enter a message:"
msgstr "输入一个信息:"
#: hellogtk.c:64
msgid "Print"
msgstr "打印"
下一步执行命令:
msgfmt -o hellogtk.mo hellogtk.po
cp hellogtk.mo /usr/share/locale/zh_CN.GB2312/LC_MESSAGE
gcc hellogtk.c –o hellogtk `gtk-config --cflags --libs`
./hellogtk
将 hello.po文件格式化为hello.mo文件,这样程序在运行时就能根据当前locale的设定来正确读取mo文件中的数据,从而显示相关语言的信息了。关于.mo文件的位置,在REDHAT中默认的目录是/usr/share/locale。将此步骤生成的mo文件复制到该的目录下,将locale设为zh_CN.GB2312,运行此程序,测试结果就变为中文了,如locale设为英文则显示仍为英文信息。
附录:源代码
/*hellogtk.c*/
#include<stdio.h>
#include<gtk/gtk.h>
#include <locale.h>
#include <libintl.h>
#define _(String) gettext(String)
#define N_(String) (String)
static GtkWidget *entry;
void PrintAndExit (GtkWidget *widget,GtkWidget *window)
{
char *str;
str=gtk_entry_get_text(GTK_ENTRY(entry));
if (str !=(char *) NULL)
printf( "%s\n", str);
}
void PrintByeAndExit (GtkWidget *widget,gpointer data)
{
printf( _("Goodbye,Gtk!\n" ));
gtk_exit(0);
}
int main( int argc,char *argv[ ] )
{
GtkWidget *window, *label,*vbox,*hbox,*button,*separator;
gtk_set_locale ();
bindtextdomain("hellogtk","/usr/share/locale/");
textdomain("hellogtk");
gtk_init(&argc,&argv);
window=gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_policy(GTK_WINDOW(window),FALSE,FALSE,FALSE);
gtk_signal_connect (GTK_OBJECT(window), "destroy",
GTK_SIGNAL_FUNC(PrintByeAndExit),NULL);
gtk_window_set_title (GTK_WINDOW(window), _("Hello Gtk!"));
gtk_container_border_width(GTK_CONTAINER(window),0);
vbox=gtk_vbox_new (FALSE,0);
gtk_container_add(GTK_CONTAINER(window),vbox);
hbox=gtk_hbox_new (FALSE,0);
gtk_box_pack_start (GTK_BOX (vbox),hbox, FALSE,FALSE,0);
label=gtk_label_new( _("Enter a message:") );
gtk_box_pack_start (GTK_BOX(hbox), label,FALSE,FALSE,0);
entry=gtk_entry_new ();
gtk_entry_set_text (GTK_ENTRY(entry),"");
gtk_editable_select_region(GTK_EDITABLE (entry),0,-1);
gtk_box_pack_start (GTK_BOX (hbox),entry,FALSE,FALSE,0);
separator=gtk_hseparator_new();
gtk_box_pack_start (GTK_BOX(vbox),separator,FALSE,FALSE,0);
button=gtk_button_new_with_label (_("Print"));
gtk_signal_connect_object(GTK_OBJECT(button),"clicked",
GTK_SIGNAL_FUNC(PrintAndExit),NULL);
gtk_box_pack_start (GTK_BOX(vbox),button,FALSE,FALSE,0);
GTK_WIDGET_SET_FLAGS (button,GTK_CAN_DEFAULT);
gtk_widget_grab_default (button);
gtk_widget_show_all (window);
gtk_main();
return(0);
}
第二种方法:使用资源文件(根据于明俭老师的文章《使用Gtk编写中文软件》)
GTK/GNOME 系列widgets中, 输入和显示已经是国际化了的. 所以用它们编写中文软件十分容易. 把西文软件改写成中文软件也十分容易.
· 在程序中包含 locale.h
· 在gtk_init前设置locale: gtk_set_locale()
· 接着调用gtk_rc_add_default_file("rcfilename"),其中rcfilename中含有缺省的fontset
· 如果不用资源文件, 则应对widget设置fontset
· 编译 gcc `gtk-config --cflags` entry.c -o entry `gtk-config --libs`
· 把文件gtkrc.zh 拷贝到当前目录下
在gtk的text组件中如果设置了font,则不能正常显示中文.解决的方法是把font释放(unref), 然后使用 gtk_fontset_load 字体集. 对于其它组件也是如此, 有的组件需要先拷贝一个 GtkStyle, 然后按上述方法解决.
下面的程序在显示中文时未使用中文平台,输入使用的是Chinput中的XIM协议支持,输出结果:
//file entry.c
#include <locale.h>
#include <gtk/gtk.h>
int main (int argc, char *argv[])
{
GtkWidget *window;
GtkWidget *vbox;
GtkWidget *entry;
GtkWidget *text;
GtkWidget *button;
gtk_set_locale();
gtk_rc_add_default_file("./gtkrc.zh");
gtk_init (&argc, &argv);
/* 新建一个窗口 */
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_widget_set_usize( GTK_WIDGET (window), 200, 500);
gtk_window_set_title(GTK_WINDOW (window), "GTK Entry");
gtk_signal_connect(GTK_OBJECT (window), "delete_event",
(GtkSignalFunc) gtk_exit, NULL);
vbox = gtk_vbox_new (FALSE, 0);
gtk_container_add (GTK_CONTAINER (window), vbox);
gtk_widget_show (vbox);
entry = gtk_entry_new_with_max_length (60);
gtk_entry_select_region (GTK_ENTRY (entry),
0, GTK_ENTRY(entry)->text_length);
gtk_box_pack_start (GTK_BOX (vbox), entry, TRUE, TRUE, 0);
gtk_widget_show (entry);
text = gtk_text_new (NULL, NULL);
gtk_text_set_editable (GTK_TEXT (text), TRUE);
gtk_box_pack_start (GTK_BOX (vbox), text, TRUE, TRUE, 0);
gtk_widget_show(text);
button = gtk_button_new_with_label ("关闭窗口");
gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC(gtk_exit),
GTK_OBJECT (window));
gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
gtk_widget_grab_default (button);
gtk_widget_show (button);
gtk_widget_show(window);
gtk_main();
return(0);
}
>gcc entry.c -o entry `gtk-config --cflags --libs`
>./entry