使用 Python/PyGObject 在 Windows 中加载 GTK-Glade 翻译

Load GTK-Glade translations in Windows using Python/PyGObject

我有一个 Python 脚本可以加载可以翻译的 Glade-GUI。在 Linux 下一切正常,但我在理解 Windows 上的必要步骤时遇到了很多麻烦。

在 Linux 下似乎需要的是:

import locale
[...]
locale.setlocale(locale.LC_ALL, locale.getlocale())
locale.bindtextdomain(APP_NAME, LOCALE_DIR)
[...]
class SomeClass():
    self.builder = Gtk.Builder()
    self.builder.set_translation_domain(APP_NAME)

locale.getlocale() returns 例如 ('de_DE', 'UTF-8')LOCALE_DIR 只是指向包含已编译 mo 文件的文件夹。

在 Windows 下,这使事情变得更加困难:

locale.getlocale() 在 Python 控制台 returns (None, None)locale.getdefaultlocale() returns ("de_DE", "cp1252")。此外,当一个人试图设置 locale.setlocale(locale.LC_ALL, "de_DE") 时会吐出这个错误:

locale.setlocale(locale.LC_ALL, "de_DE")
File "C:\Python34\lib\locale.py", line 592, in setlocale
return _setlocale(category, locale)
locale.Error: unsupported locale setting

我把它留给 reader 来推测为什么 Windows 不接受最常见的语言代码。因此,人们被迫使用以下行之一:

此外 Windows 上的 locale 模块没有 bintextdomain 功能。为了使用它,需要导入 ctypes:

import ctypes
libintl = ctypes.cdll.LoadLibrary("intl.dll")
libintl.bindtextdomain(APP_NAME, LOCALE_DIR)
libintl.bind_textdomain_codeset(APP_NAME, "UTF-8")

所以我的问题,除了它是如何工作的,还有:

编辑

我的文件夹结构(有一个 de 文件夹就足够了吗?我尝试使用 deu_deu 文件夹但没有帮助):

├── gnome_preamble.py
├── installer.cfg
├── pygibank
│   ├── __init__.py
│   ├── __main__.py
│   ├── mo
│   │   └── de
│   │       └── LC_MESSAGES
│   │           └── pygibank.mo
│   ├── po
│   │   ├── de.po
│   │   └── pygibank.pot
│   ├── pygibank.py
│   └── ui.glade
└── README.md

答案的简短摘要

mo-文件应该以这种方式进入 gnome-packages:

├── gnome
│   └── share
│       └── locale
│           └── de
|               └── LC_MESSAGES
|                    └── pygibank.mo

你很接近。这是一个非常复杂的课题。

正如我在 Question 10094335 and in Question 3678174 中所写:

要将区域设置设置为用户当前的区域设置,请不要调用:

locale.setlocale(locale.LC_ALL, locale.getlocale())

只需致电:

locale.setlocale(locale.LC_ALL, '')

Python setlocale reference documentation 中所述。

This sets the locale for all categories to the user’s default setting (typically specified in the LANG environment variable).

请注意 Windows 没有设置 LANG 环境变量,因此,您需要在该行之前执行此操作:

import sys
import os
import locale

if sys.platform.startswith('win'):
    if os.getenv('LANG') is None:
        lang, enc = locale.getdefaultlocale()
        os.environ['LANG'] = lang

这也将使 gettext 用于 in-Python 翻译。

这是如何工作的,您可以在此处查看源代码:

https://github.com/python/cpython/blob/master/Modules/_localemodule.c#L90

特别是您遇到的错误:

locale.Error: unsupported locale setting

这里表示:

https://github.com/python/cpython/blob/master/Modules/_localemodule.c#L112

这只是 C 调用 setlocale 使用给定参数失败的一般错误消息。

C 调用 setlocalelocale.h header 中定义。在Linux中,这是:

在Windows中使用的是:

在 Windows locale.h 文档中,您可以阅读:

The set of language and country/region strings supported by setlocale are listed in Language Strings and Country/Region Strings.

这指向:

如您所见,对于 2010 版本,setlocale 函数需要您发现的格式中的语言环境:deu_deu,这与 Linux 所期望的格式不同版本 de_DE。您唯一的选择是使用 os-dependent 语言环境列表来设置语言环境。真的很伤心。

这里还有一个问题。如果您更改工具链的版本,您可以看到 setlocale 函数的新版本现在与 Linux/POSIX 的功能更接近:

american english en-US

Visual Studio 2010 是最后一个支持旧格式的版本,从 2012 版开始,预计将使用新的语言环境格式。

如您所想,您需要使用的工具链版本取决于您正在使用的 CPython 解释器所针对的工具链版本。不知道你用的是哪个版本,官方说的Python Developer's Guide:

Python 3.5 and later use Microsoft Visual Studio 2015. [...] Python 3.3 and 3.4 use Microsoft Visual Studio 2010. [...] Most Python versions prior to 3.3 use Microsoft Visual Studio 2008. [...]

这都与Python locale模块有关。现在,对于 gettext 模块或 locale 模块中的 gettext related functions,这是另一个名为 libintl.

的 C 库

libintl 是所谓的 C 库,它是所有这些翻译魔法的 gettext 的一部分:

本文档的一个相关部分说:

Note that on GNU systems, you don’t need to link with libintl because the gettext library functions are already contained in GNU libc.

但在 Windows 中,由于 Question 10094335 中解释的问题,您需要加载 PyGObject 使用的 libintl 库,也就是说,与它完全相同在构建期间被 linked。完成您已经编写的步骤。

Which intl.dll do I need to include? (I tried the gnome/libintl-8.dll from this source: http://sourceforge.net/projects/pygobjectwin32/, (pygi-aio-3.14.0_rev19-setup.exe))

所以,是的。在构建 pygobject AIO 时用于 link 的那个。

How can I check if the e.g. locale deu_deu gets the correct /mo/de/LC_MESSAGES/appname.mo/

配置一些消息并注意它们是否显示已翻译。请注意,"/mo/de/LC_MESSAGES/appname.mo/"不是文件夹,appname.mo是文件

查看我关于如何从 Glade 文件创建翻译 .po 文件的第一个答案。