如何绑定文本域到本地文件夹下的gettext GTK3(How to bind a text dom

2019-06-23 12:11发布

随着gettext ,你可以使用默认的系统范围内的区域设置目录,或使用指定一个自己bindtextdomain 。 直接从源在运行程序时,当编译的.mo翻译文件不在系统的默认位置可用,这非常有用。

在Python中你可以这样做:

import gettext
from gettext import gettext as _
gettext.bindtextdomain('nautilus-image-manipulator', '/path/to/mo/folder')
gettext.textdomain('nautilus-image-manipulator')

其中/path/to/mo/folder包含熟悉fr/LC_MESSAGES/nautilus-image-manipulator.mo结构。 调用是这样的:

print _("Delete this profile")

返回从本地的.mo文件正确地翻译字符串,非常感谢你。

在GTK + 2 / PyGTK的,存在着gtk.glade.bindtextdomain ,但我不知道是否有在GTK + 3 / PyGObject任何等效。

为了给你一个具体的例子,这是何等的图片鹦鹉螺手;的UI从其格莱德文件中创建:

from gi.repository import Gtk
builder = Gtk.Builder()
builder.set_translation_domain('nautilus-image-manipulator')
builder.add_from_file(ui_filename)
return builder

未从格莱德文件(即从代码中设置)内置的UI显示的零件正确地翻译,而是从格莱德文件中的字符串在英语仍然显示。

在我看来,我就是缺少某种的呼叫builder.bind_text_domain('nautilus-image-manipulator', '/path/to/mo/folder')之前调用builder.set_translation_domain ...任何想法如何执行呢?

Answer 1:

在PyGTK中您可以使用Gtk.Builder了。 因此在PyGTK的Gtk.Builder文档:

http://developer.gnome.org/pygtk/stable/class-gtkbuilder.html#properties-gtkbuilder

平移已标记在接口描述为可翻译的属性值时的翻译域使用。 如果翻译域是无,GtkBuilder使用gettext的(),否则dgettext()。 默认值:无

也就是说,Gtk.Builder使用dgettext()从 “C库”。 问题是Python的gettext的模块,功能bindtextdomain(),由于某种原因未知对我来说,没有设置“C库”。 该选项是使用本地化模块也暴露了接口。 从Python语言环境模块文档:

http://docs.python.org/library/locale#access-to-message-catalogs

本地化模块暴露在提供此接口的系统C库的gettext接口。 它由功能的gettext(),dgettext(),dcgettext(),textdomain(),bindtextdomain(),和bind_textdomain_codeset的()。 这些类似于了gettext模块中的相同的功能,但使用C库的二进制格式对消息目录,并用于定位消息目录C库的搜索算法。

Python应用程序通常应该发现不需要调用这些功能,而应使用gettext。 一种已知的例外是用另外的C库在内部调用gettext的()或dcgettext()链接的应用程序。 对于这些应用,可能需要绑定的文本域,从而使图书馆能够正确定位自己的信息目录。

这是目前的情况。 什么是黑客:S

这将做到这一点,文件test.py:

from gi.repository import Gtk
from os.path import abspath, dirname, join, realpath
import gettext
import locale

APP = 'myapp'
WHERE_AM_I = abspath(dirname(realpath(__file__)))
LOCALE_DIR = join(WHERE_AM_I, 'mo')

locale.setlocale(locale.LC_ALL, '')
locale.bindtextdomain(APP, LOCALE_DIR)
gettext.bindtextdomain(APP, LOCALE_DIR)
gettext.textdomain(APP)
_ = gettext.gettext

print('Using locale directory: {}'.format(LOCALE_DIR))

class MyApp(object):

    def __init__(self):
        # Build GUI
        self.builder = Gtk.Builder()
        self.glade_file = join(WHERE_AM_I, 'test.glade')
        self.builder.set_translation_domain(APP)
        self.builder.add_from_file(self.glade_file)

        print(_('File'))
        print(_('Edit'))
        print(_('Find'))
        print(_('View'))
        print(_('Document'))

        # Get objects
        go = self.builder.get_object
        self.window = go('window')

        # Connect signals
        self.builder.connect_signals(self)

        # Everything is ready
        self.window.show()

    def main_quit(self, widget):
        Gtk.main_quit()

if __name__ == '__main__':
    gui = MyApp()
    Gtk.main()

我格莱德文件test.glade:

<?xml version="1.0" encoding="UTF-8"?>
<interface>
  <!-- interface-requires gtk+ 3.0 -->
  <object class="GtkWindow" id="window">
    <property name="can_focus">False</property>
    <property name="window_position">center-always</property>
    <property name="default_width">400</property>
    <signal name="destroy" handler="main_quit" swapped="no"/>
    <child>
      <object class="GtkBox" id="box1">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="orientation">vertical</property>
        <child>
          <object class="GtkLabel" id="label1">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="label" translatable="yes">File</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">0</property>
          </packing>
        </child>
        <child>
          <object class="GtkLabel" id="label2">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="label" translatable="yes">Edit</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">1</property>
          </packing>
        </child>
        <child>
          <object class="GtkLabel" id="label3">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="label" translatable="yes">Find</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">2</property>
          </packing>
        </child>
        <child>
          <object class="GtkLabel" id="label4">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="label" translatable="yes">View</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">3</property>
          </packing>
        </child>
        <child>
          <object class="GtkLabel" id="label5">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="label" translatable="yes">Document</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">4</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
</interface>

请记住,在来创建MO / LANG / LC_MESSAGES / myapp.mo基础上的.po与提取:

xgettext --keyword=translatable --sort-output -o en.po test.glade

它是什么样子:

亲切的问候



Answer 2:

该解决方案以激活gettext的翻译用GTK / Python的Windows下是elib_intl.py这是很容易找到与谷歌的文件。 这使得在一块空地UI代码和文本翻译文本。

下面是用于以下环境中的代码:

Windows 7中的Python 2.7的Gtk 3+加载:pygi-AIO-3.10.2-win32_rev18-SETUP.EXE

它应该在任何窗口工作,也为Python 3 elib_intl.py可以用PyGTK的(GTK 2)使用。

from gi.repository import Gtk, Gdk
import cairo

import locale       #for multilanguage support
import gettext
import elib_intl
elib_intl.install("pdfbooklet", "share/locale")

如果您在使用GTK 3,您可能会收到一个错误:行447:

libintl = cdll.intl

此错误指示:找不到模块。 其原因是,在Gtk3,DLL的名称已更改。 它不再是intl.dll。 在所描述的Pygi安装名称为:的libintl-8。 您必须更换其中由provoques错误的行:

libintl = cdll.LoadLibrary("libintl-8.dll")

你可以在这里找到一个完整的工作示例: pdfBooklet 2.4.0 (警告:尚未线的时候我写)

由于节食者谁写elib_intl Verfaillie



Answer 3:

赏金失败如此惨败,吸引了Mac OS X的答案后,好了,我必须做我自己的研究。 下面是我使用的代码片段:

import locale, ctypes, sys, os
import gettext

# setup textdomain and install _() for strings from python
gettext.install('domain', '/path/to/locale/dir')

try:
    if hasattr(locale, 'bindtextdomain'):
        libintl = locale
    elif os.name == 'nt':
        libintl = ctypes.cdll.LoadLibrary('libintl-8.dll')
    elif sys.platform == 'darwin':
        libintl = ctypes.cdll.LoadLibrary('libintl.dylib')

    # setup the textdomain in gettext so Gtk3 can find it
    libintl.bindtextdomain('domain', '/path/to/locale/dir')

except (OSError, AttributeError):
    # disable translations altogether for consistency
    gettext.install('')

后来,当你有Gtk.Builder,设置域名:

builder.set_translation_domain('domain')

这如果gettext的图书馆只会工作libintl是在库路径,否则优雅地失败。 对于transaltions工作,你需要安装的gettext的依赖。



文章来源: How to bind a text domain to a local folder for gettext under GTK3