国际化

国际化

GLib 不会强迫其用户使用任何特定的本地化方法。但由于 GLib 本身是使用 `gettext()` 机制本地化的,因此以易于使用的形式提供默认标准 `gettext()` 支持宏显得十分自然。

要在应用程序中使用这些宏,您必须包含 `<glib/gi18n.h>`。要在库中使用,您必须在为库适当地定义 `GETTEXT_PACKAGE` 宏之后包含 `<glib/gi18n-lib.h>`

#define GETTEXT_PACKAGE "gtk4"
#include <glib/gi18n-lib.h>

对于应用程序,请注意,您还必须早早地 `main()` 中调用 `bindtextdomain()`, `bind_textdomain_codeset()`, `textdomain()` 和 `setlocale()` 以使 `gettext()` 正常工作。例如

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

int
main (int argc, char **argv)
{
  setlocale (LC_ALL, "");
  bindtextdomain (GETTEXT_PACKAGE, DATADIR "/locale");
  bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
  textdomain (GETTEXT_PACKAGE);

  // Rest of your application.
}

其中 `DATADIR` 通常由 Automake 或 Meson 提供。

对于库,您只需在初始化函数中调用 `bindtextdomain()` 和 `bind_textdomain_codeset()`。如果您的库没有初始化函数,您可以在第一个翻译信息之前调用这些函数。

gettext 手册 介绍了如何将 gettext 集成到项目的构建系统和工作流中的详细信息。

GLib 提供了各种便利的 C 预处理器宏,使像 xgettext 这样的工具可以轻松地从库或应用程序的源代码中提取可翻译的字符串。包含 `<glib/gi18n.h>` 或 `<glib/gi18n-lib.h>` 时会定义这些宏。

_(String)
标记一个字符串进行翻译。如果存在翻译,这个字符串将在运行时替换为其翻译;否则,它将按原样传递。
N_(String)

标记一个字符串进行翻译。与 `_()` 不同的是,此宏不会用其翻译替换该字符串;当可翻译字符串位于 `struct` 或数组声明中时,这很有用,例如

static const char *messages[] = {
  N_("some very meaningful message"),
  N_("and another one"),
};

使用字符串时由开发人员负责调用 `gettext()`,例如

g_print ("%s", idx >= G_N_ELEMENTS (messages)
         ? _("default message")
         : gettext (messages[idx]));
C_(Context, String)

使用 `gettext` 获得 `String` 的翻译。`Context` 用作上下文。这主要用于可能需要不同翻译的短字符串,具体取决于其用法的上下文。例如

label1 = C_("Navigation", "Back");
label2 = C_("Body part", "Back");

如果您正在使用 `C_()` 宏,则需要确保在提取信息时向 `xgettext` 传递 `--keyword=C_:1c,2`。这仅适用于版本高于 0.15 的 GNU gettext。

此宏自 GLib 2.16 起可用

NC_(Context, String)

仅标记一个字符串进行翻译,带上下文。类似于 `N_()`,但允许您向可翻译字符串添加上下文,例如

static const char *messages[] = {
  NC_("some context", "some very meaningful message"),
  NC_("some context", "and another one")
};

使用字符串时由开发人员负责调用 g_dpgettext2(),例如

g_print ("%s", idx >= G_N_ELEMENTS (messages)
         ? g_dpgettext2 (NULL, "some context", "a default message")
         : g_dpgettext2 (NULL, "some context", messages[idx]);

如果您正在使用 `NC_()` 宏,则需要确保在提取信息时向 `xgettext` 传递 `--keyword=NC_:1c,2`。这仅适用于版本高于 0.15 的 GNU gettext。自 0.40.1 版本起,Intltool 开始支持 `NC_()` 宏。

此宏自 GLib 2.18 起可用

Q_(String)

与 `_()` 类似,但在可翻译字符串中处理上下文。这样做的好处是,该字符串可以用前缀修饰,以保证唯一性并向翻译人员提供上下文。

String 由两个部分组成,中间用 | 字符分隔。前面的部分是前缀,不能翻译;后面的部分是可以翻译的消息。

gettext 手册中给出的一种用例是 GUI 翻译,在此我们可以将两个“打开”菜单项区分为 "File|Open""Printer|Open"。另一个用例是字符串“俄语”,该字符串的翻译可能有所不同,具体取决于它是字符集还是语言的名称。这可以通过使用 "charset|Russian""language|Russian" 来解决。

另请参阅 C_() 宏,了解使用上下文标记可翻译字符串的另一种方法。

如果您使用的是 Q_() 宏,则需要确保在提取消息时将 --keyword=Q_ 传递给 xgettext。如果您使用的是 0.15 版以后的 GNU gettext,还可以使用 --keyword=Q_:1g 让 xgettext 将上下文字符串拆分为 .po 文件中的 msgctxt 行。

此宏自 GLib 2.4 版起可用