在gtk+程序中显示中文说明

 在gtk+程序中显示中文说明
简单地说,gtk只认utf8编码,由glibc负责转换编码到utf8编码或直接用utf8编码。
(一)应用程序中该做的事情(确定所用mo文件的位置)
首先用函数textdomain设置应用程序的中文信息(mo文件)所在的位置,姑且称为“域”
如:
setlocale( LC_ALL, "zh_CN.GB2312" ); 
textdomain( "test" ); // 设置代表该应用程序中文信息的名称,默认的“域”名为message
bindtextdomain ( "test", "/usr/local/share/locale"); // 设置信息所在的目录,默认情况下该目录值被设置为/usr/share/locale
这样gettext函数(下面将提到)就会在目录/usr/local/share/locale/zh_CN.GB2312/LC_MESSAGES中去中文信息文件test.mo。
其中***代表程序的locale环境变量对应语言变量LC_MESSAGES的值
......
在gtk+程序中显示中文说明
(一)应用程序中该做的事情(确定所用mo文件的位置)
首先用函数textdomain设置应用程序的中文信息(mo文件)所在的位置,姑且称为“域”
如:
setlocale( LC_ALL, "zh_CN.GB2312" ); 
textdomain( "test" ); // 设置代表该应用程序中文信息的名称,默认的“域”名为message
bindtextdomain ( "test", "/usr/local/share/locale"); // 设置信息所在的目录,默认情况下该目录值被设置为/usr/share/locale
这样gettext函数(下面将提到)就会在目录/usr/local/share/locale/zh_CN.GB2312/LC_MESSAGES中去中文信息文件test.mo。
其中***代表程序的locale环境变量对应语言变量LC_MESSAGES的值
程序中,每一个将被显示成中文的字符串都必须经过gettext函数处理。
如:
gtk_button_new_with_label( "ok" );
如果要将该按钮的标签名显示成中文,那么必须将这条语句改成 gtk_button_new_with_label( (void*)gettext( "ok" ) );
gettext工作原理
char *str = "string";
gettext( str );
1. 根据locale和textdomain的设置寻找对应mo文件;
   if 没找到 then 返回str; else goto 2;
2. 以str串为id找相应的翻译串;
   if 没找到 then 返回str; else goto 3;
3. 把翻译串从 编码1 转化成 编码2;
   if 转换成功 then 返回经编码转换后的翻译串; else 返回翻译串(或其他?);
   编码1:由mo文件的属性charset决定
   编码2:由locale决定,如:zh_CN.GB2312决定编码2为GB2312编码
(二)mo文件的制作
1. 根据源程序生成po文件,如:xgettext --keyword="gettext" try.c -o test.po
   例:设xgettext程序从文件中找到gettext("pepole"),则在po文件中有如下内容:
msgid "people"
msgstr ""
2. 在po文件中,根据msgid部分填写的msgstr部分,
例:
msgid "people"
msgstr "人民"
   注意,如下设置po文件的相应内容:
   "Content-Type: text/plain; charset=CHARSET
"
   "Content-Transfer-Encoding: 8bit
"
   此处charset为msgstr部分的编码格式,
由于gtk+的文本输入都是UTF-8格式,所以此处用utf-8编码格式编辑po文件(填入msgstr部分的简体中文),并令charset=
CHARSET,这样msgstr部分的简体中文被保存为UTF-8编码格式。这样,如果gettext从与该文件对应的mo文件中取出的信息就是简体中
文的UTF-8编码,注意:此处charset=CHARSET则gettext的第三步没有执行,所以返回的是utf-8串(因为文本输入时的编码格式
为utf-8)
   Content-Transfer-Encoding暂时将它写做8bit
注:如果此处charset=有效编码,那么由gettext返回的中文编码格式由locale决定,此时还需将gettext的返回中文串转成utf-
8格式,这样就进行了两次编码转换;而如果charset=无效编码,则gettext直接返回中文utf-8串,而没必要进行编码转换,效率更高。
3. 生成mo文件,msgfmt test.po -o test.mo
4. 拷贝mo文件到程序中设置的相应位置/usr/local/share/locale/***/LC_MESSAGES
(三)环境设置
设置好gtk+所用的中文字体,如果所用字体是GB2312编码,那么可以想象gtk是这样工作(实际不是这么处理的,但效果是一样的):将输入的UTF-8编码转化成GB2312码,然后告诉X服务器用 该码 和 该字体文件 显示相应字行.
(四)例子
// try.c文件内容
#include 
#include 
#define _(str) (void*)gettext(str)
gint delete_event( GtkWidget *win, GdkEvent *e, gpointer arg )
{
    g_print( "quite application!
" );
    return FALSE;
}
void destroy( GtkWidget *win, gpointer arg )
{
    g_print( "destroy window!
" );
    gtk_main_quit();
}
int main( int argc, char *argv[] )
{
    GtkWidget *window,*button;
    unsigned char *s;
    textdomain( "testmo" );
    printf( "%s
", bindtextdomain( "testmo", "/usr/share/locale" ) );
    gtk_init( &argc, &argv );
    window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
    g_signal_connect( G_OBJECT(window), "delete_event", G_CALLBACK(delete_event), NULL );
    g_signal_connect( G_OBJECT(window), "destroy", G_CALLBACK(destroy), NULL );
    button = gtk_button_new_with_label( _("ok") );
    gtk_container_add( GTK_CONTAINER( window ), button );
    gtk_widget_show( button );
    gtk_widget_show( window );
    gtk_main();
    return 0;
}
// 生成po文件,编码方式utf-8
// gcc -E try.c -o temp.c; xgettext temp.c -o test.po; rm -f temp.c
// 或者 xgettext --keyword=_ try.c -o test.po更方便,默认的keyword是gettext,此处增加keyword _
// 翻译po文件(以utf-8编码格式填写),运行msgfmt test.po test.mo
// charset=无效编码名,即:CHARSET为无效编码名。可有程序iconv --list查看支持的编码名
// 拷贝test.mo文件到/usr/share/locale/zh_CN.GB2312/LC_MESSAGES目录下
// 已翻译的po文件的内容
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR Free Software Foundation, Inc.
# FIRST AUTHOR , YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION
"
"POT-Creation-Date: 2005-03-07 20:31-0500
"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE
"
"Last-Translator: FULL NAME 
"
"Language-Team: LANGUAGE 
"
"MIME-Version: 1.0
"
"Content-Type: text/plain; charset=CHARSET
"
"Content-Transfer-Encoding: 8bit
"
#: try.c:31
msgid "ok"
msgstr "确定"
// 编译程序,设置locale,运行程序,正常情况应该有中文显示
$gcc -o app try.c
$export LC_ALL=zh_CN.GB2312
$./app

你可能感兴趣的:(在gtk+程序中显示中文说明)