使用 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 中是否有任何等价物。
举个具体的例子,Nautilus Image Manipulator;s UI是从它的 Glade 文件创建的:
from gi.repository import Gtk
builder = Gtk.Builder()
builder.set_translation_domain('nautilus-image-manipulator')
builder.add_from_file(ui_filename)
return builder
不是从 Glade 文件构建(即从代码设置)的部分 UI 显示正确翻译,但 Glade 文件中的字符串仍以英文显示。
在我看来,在调用 builder.set_translation_domain
...知道如何执行此操作吗?
最佳答案
在 PyGtk 中你也可以使用 Gtk.Builder。根据 PyGtk Gtk.Builder 文档:
http://developer.gnome.org/pygtk/stable/class-gtkbuilder.html#properties-gtkbuilder
The translation domain used when translating property values that have been marked as translatable in interface descriptions. If the translation domain is None, GtkBuilder uses gettext(), otherwise dgettext(). Default value: None
也就是说,Gtk.Builder 使用“C 库”中的 dgettext()。问题是 Python 的 gettext 模块,函数 bindtextdomain(),出于某种我不知道的原因,没有设置“C 库”。选项是使用也公开该接口(interface)的 locale 模块。来自 Python 语言环境模块文档:
http://docs.python.org/library/locale#access-to-message-catalogs
The locale module exposes the C library’s gettext interface on systems that provide this interface. It consists of the functions gettext(), dgettext(), dcgettext(), textdomain(), bindtextdomain(), and bind_textdomain_codeset(). These are similar to the same functions in the gettext module, but use the C library’s binary format for message catalogs, and the C library’s search algorithms for locating message catalogs.
Python applications should normally find no need to invoke these functions, and should use gettext instead. A known exception to this rule are applications that link with additional C libraries which internally invoke gettext() or dcgettext(). For these applications, it may be necessary to bind the text domain, so that the libraries can properly locate their message catalogs.
这是当前的情况。真是个黑客: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()
我的 Glade 文件 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 创建 mo:
xgettext --keyword=translatable --sort-output -o en.po test.glade
它的样子:
亲切的问候
关于python - GTK3下如何将文本域绑定(bind)到本地文件夹以获取gettext,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10094335/