您的位置:首页 > 其它

GTK+浅谈之十一国际化多语言支持及发布

2015-09-24 17:19 405 查看


一、简介

Gtk+2.0用gettext软件包来实现国际化(对多种语言进行支持)。gettext软件包是GNU工程中解决国际化问题的重要工具,它支持C/C++和J***A语言,它在开源界应用相当广泛,GNOME/GTK+的国际化问题都是用它来解决的,正常的情况下GNU/LINUX系统是默认安装这一软件包的。


二、详解

(1)代码:internation.c

#include <gtk/gtk.h>
#include <libintl.h>
#include <locale.h>
#include <glib/gi18n.h>

#define PACKAGE "internation"
#define LOCALEDIR "./locale"

//#define _(string)  gettext(string)
//#define N_(string) string

static GtkWidget *entry = NULL;

void on_button_clicked(GtkWidget *button, gpointer data)
{
    gtk_entry_set_text(GTK_ENTRY(entry), _("this text will put in the entry"));
}

int main(int argc, char *argv[])
{
    GtkWidget *window;
    GtkWidget *vbox;
    GtkWidget *button;
    GtkWidget *label;

//    setlocale (LC_ALL, "");
    bindtextdomain(PACKAGE, LOCALEDIR);
    textdomain(PACKAGE);     //pass .mo

    gtk_init(&argc, &argv);
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(gtk_main_quit), NULL);
    gtk_window_set_title(GTK_WINDOW(window), _("window"));
    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
    gtk_container_set_border_width(GTK_CONTAINER(window), 10);

    vbox = gtk_vbox_new(FALSE, 0);
    gtk_container_add(GTK_CONTAINER(window), vbox);

    label = gtk_label_new(_("this is a international application"));
    gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 5);

    button = gtk_button_new_with_label(_("new button"));
    gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 5);
    g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(on_button_clicked), NULL);

    entry = gtk_entry_new();
    gtk_box_pack_start(GTK_BOX(vbox), entry, FALSE, FALSE, 5);

    gtk_widget_show_all(window);
    gtk_main();
    return TRUE;
}
编译运行:

gcc -o internation internation.c `pkg-config --cflags --libs gtk+-2.0`



(2)国际化编程

源代码中#include <libintl.h>提供对gettext的支持;#include <locale.h>对locale的支持;bindtextdomain(PACKAGE,LOCALEDIR)用来设定国际化翻译包所在位置,PACKAGE国际化翻译包名(省略了后缀.mo),LOCALEDIR翻译包所在的顶级目录(还需要/zh_CN/LC_MESSAGES子级目录);textdomain(PACKAGE)用来设定国际化翻译包名称。

第一步:生成po文件:

xgettext -k_ -o internation.po internation.c
-j参数:表示不覆盖生成过的po文件

-k参数:指定翻译字符以何种宏定义括起,代码中使用的是_()所以用-k_

输入文件可以是*.c表示扫描所有的c文件,如果是glade生成的UI文件,可以使用 *.gladea

第二步:翻译

vim internation.po,msgid后面的内容为代码中的英文,msgstr后面的内容为要翻译的中文(注意:将charset=CHARSET改为charset=UTF-8)。

若没有修改charset=UTF-8,生成internation.mo是会出现如下(无法实现中文化):

internation.po: 警告:字符集“CHARSET”不是可移植的编码名称。
                      将消息转换为用户字符集可能不工作。
修改完毕后:

# 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 <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-09-24 16:51+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

#: internation.c:16
msgid "this text will put in the entry"
msgstr "此文本将被放入单行录入控件之中"

#: internation.c:33
msgid "window"
msgstr "主窗口"

#: internation.c:40
msgid "this is a international application"
msgstr "这是一个国际化的应用程序"

#: internation.c:43
msgid "new button"
msgstr "按钮"
第三步:生成mo文件

msgfmt -o internation.mo internation.po
mkdir -p ./locale/zh_CN/LC_MESSAGES/
mv internation.mo ./locale/zh_CN/LC_MESSAGES/
在当前目录下创建locale目录,其下创建子目录locale/zh_CN/LC_MESSAGES,将internation.mo移到./locale/zh_CN/LC_MESSAGES目录下(Linux系统的国际化翻译包默认的目录是/usr/share/locale,中文翻译目录/usr/share/locale/zh_CN/LC_MESSAGES/)。

然后再运行程序(不用重新编译程序)即可完成翻译:



(3)自动生成Makefile与打包

运用AUTOCONF和AUTOMAKE这两个工具,自动生成Makefile文件,并能实现打包(生成*.tar.gz格式的源代码包)功能。与这两个工具相关的配置文件分别是configure.in和 Makefile.am。

第一步:在internation.c的目录下执行autoscan命令,生成configure.scan文件。

第二步:mv configure.scan configure.in,并编辑configure.in,在其中加入AC_INIT(internation.c)和AM_INIT_AUTOMAKE(internation, 1.0)表示软件包名为internation,版本为1.0(这样在最后make编译后,执行make dist会生成一个名为 表示软件包名为internation-1.0.tar.gz源代码包)。在最后一行加入AC_OUTPUT(Makefile)表示输出Makefile文件。onfigure.in文件中还有许多宏定义,可以参考autobook一书。

#                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_PREREQ([2.63])
#AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])
AC_INIT(internation.c)
AM_INIT_AUTOMAKE(internation, 1.0)
AC_CONFIG_SRCDIR([internation.c])
AC_CONFIG_HEADERS([config.h])

# Checks for programs.
AC_PROG_CC

# Checks for libraries.

# Checks for header files.
AC_CHECK_HEADERS([libintl.h locale.h])

# Checks for typedefs, structures, and compiler characteristics.

# Checks for library functions.
AC_CHECK_FUNCS([setlocale])

AC_OUTPUT(Makefile)
第三步:执行aclocal命令,生成aclocal.m4宏文件。

第四步:执行autoconf命令,生成configure可执行脚本。

第五步:编辑Makefile.am文件:
AUTOMAKE_OPTIONS = foreign
INCLUDES = `pkg-config --cflags gtk+-2.0`
LIBS = `pkg-config --libs gtk+-2.0`
bin_PROGRAMS = internation
internation_SOURCES = internation.c
其中:第一行为AUTOMAKE命令的参数,表示为外部的,不按GNU标准(即不加说明、安装、更改记录等文件) ;第二行表示包含文件的目录;第三行表示动态链接库的目录和所要链接的库;第四行表示输出的可执行文件名;最后一行表示可执行文件的源程序文件,可以有多 个文件名。

第六步:创建touch config.h.in(一般定义些变量,此处仅创建以执行下一步)和mkdir py创建文件夹,然后执行automake --add-missing -copy,执行cp py/Makefile.in ./将Makefile.in复制到当前目录。

第七步:即可通过./configure生成Makefile,make编译,make install安装。执行make dist会在当前目录下生成internation-1.0.tar.gz源代码包,这个源代码包可以对外发布了。





三、总结

(1)修改charset=UTF-8在centos上运行正常,还不确定在windows需要设置成哪种,可自行调整。

(2)#define _(string) gettext(string)宏在#include <glib/gi18n.h>中有定义,gettext是从国际化编译包中提取相关的输出信息,gettext的两个重要工具:xgettext和msgfmt。

(3)此处.po只翻译为中文,也可翻译成其他语种,从而进行更广泛的国际化支持。

(4)源码已上传到CSDN:http://download.csdn.net/detail/taiyang1987912/9137149

(5)若有建议,请留言,在此先感谢!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: