Chinaunix首页 | 论坛 | 博客
  • 博客访问: 92225
  • 博文数量: 41
  • 博客积分: 1531
  • 博客等级: 上尉
  • 技术积分: 420
  • 用 户 组: 普通用户
  • 注册时间: 2005-05-17 10:15
文章分类

全部博文(41)

文章存档

2014年(2)

2012年(1)

2011年(2)

2008年(9)

2007年(2)

2006年(5)

2005年(20)

分类: LINUX

2005-05-19 11:04:37

在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

阅读(2949) | 评论(0) | 转发(0) |
0

上一篇:惭愧啊

下一篇:惊叹,

给主人留下些什么吧!~~