翻译用 Glade 和 Python 编写的 GTK UI
Translate GTK UI written in Glade and Python
我花了一些时间四处寻找答案,并且找到了很多答案。理论上我的代码应该可以工作,但事实并非如此。
首先我会 post 最简单的代码,然后我会描述问题。
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>
test.py :
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
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.getlocale())
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()
en.po :
# 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.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-06-15 15:18+0200\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"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: test.glade:66
msgid "Document"
msgstr "Dokumentumok"
#: test.glade:30
msgid "Edit"
msgstr "Szerkesztés"
#: test.glade:18
msgid "File"
msgstr "Fájl"
#: test.glade:42
msgid "Find"
msgstr "Keresés"
#: test.glade:54
msgid "View"
msgstr "Nézet"
而 myapp.mo 文件位于 mo/hu_HU/LC_MESSAGES/myapp.mo
问题:
python 代码中的字符串被完美地翻译了(所以当我使用 set_label 时它也可以工作),但是 glade 文件中的字符串将无法工作,即使它们是翻译成功。所以问题不在于语言环境的加载。
输出:
Using locale directory: /home/daniel/Downloads/test/mo
Fájl
Szerkesztés
Keresés
Nézet
Dokumentumok
图形用户界面:
我在 Gnome 桌面上使用 ubuntu 20.04,系统语言是目标语言 (hu_HU)
当我使用正确的编码代替 en.po
中的单词 CHARSET
时,代码对我有用 - 即。 UTF-8
"Content-Type: text/plain; charset=UTF-8\n".
顺便说一句:
当我在console/terminal
中使用
msgfmt -c en.po -o myapp.mo
然后它甚至显示警告
en.po: warning: Charset "CHARSET" is not a portable encoding name.
Message conversion to user's charset might not work.
并确认 CHARSET
必须更改。
它还显示其他值的警告 - PACKAGE VERSION
、YEAR-MO-DA HO:MI+ZONE
、FULL NAME <EMAIL@ADDRESS>
、LANGUAGE
- 但它们并不那么重要。
po/en.po:7: warning: header field 'Project-Id-Version' still has the initial default value
po/en.po:7: warning: header field 'PO-Revision-Date' still has the initial default value
po/en.po:7: warning: header field 'Last-Translator' still has the initial default value
po/en.po:7: warning: header field 'Language-Team' still has the initial default value
po/en.po:7: warning: header field 'Language' still has the initial default value
编辑:
似乎代码集 LC_ALL
- locale.setlocale(locale.LC_ALL, ...)
但在我的系统中(Linux Mint 19.2 基于 Ubuntu 18.04)我也有 LANG=pl_PL.UTF-8
, LANGUAGE=pl_PL:pl
也许这会有所作为。但是我不能在代码中设置它 locale.setlocale(locale.LANG, ...)
编辑:
您确认变量 LANGUAGE
是问题所在。
如果 LANGUAGE
是 hu:en
或 hu
那么 .mo
文件必须在文件夹 hu
而不是 hu_HU
顺便说一句:
我检查过我在 /usr/share/locale/
中也有文件夹 hu
但是当我 运行
locale -a | grep hu
然后显示给我
hu_HU
hu_HU.UTF-8
和 locale.setlocale(locale.LC_ALL, 'hu')
给我错误,但 locale.setlocale(locale.LC_ALL, 'hu_HU')
运行 没有错误。
我创建了两个包含不同单词 mo/hu_HU/...
和 mo/pl_PL/...
的文件夹,即使我使用 locale.setlocale(locale.LC_ALL, 'hu_HU')
我也会看到来自 pl_PL
的单词。但是当我删除 locale.setlocale()
然后我看到英文单词。
要查看来自 hu_HU
的文字,我必须 运行 在控制台中将其设为
LANGUAGE=hu_HU python test.py
我花了一些时间四处寻找答案,并且找到了很多答案。理论上我的代码应该可以工作,但事实并非如此。 首先我会 post 最简单的代码,然后我会描述问题。
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>
test.py :
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
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.getlocale())
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()
en.po :
# 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.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-06-15 15:18+0200\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"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: test.glade:66
msgid "Document"
msgstr "Dokumentumok"
#: test.glade:30
msgid "Edit"
msgstr "Szerkesztés"
#: test.glade:18
msgid "File"
msgstr "Fájl"
#: test.glade:42
msgid "Find"
msgstr "Keresés"
#: test.glade:54
msgid "View"
msgstr "Nézet"
而 myapp.mo 文件位于 mo/hu_HU/LC_MESSAGES/myapp.mo
问题:
python 代码中的字符串被完美地翻译了(所以当我使用 set_label 时它也可以工作),但是 glade 文件中的字符串将无法工作,即使它们是翻译成功。所以问题不在于语言环境的加载。
输出:
Using locale directory: /home/daniel/Downloads/test/mo
Fájl
Szerkesztés
Keresés
Nézet
Dokumentumok
图形用户界面:
我在 Gnome 桌面上使用 ubuntu 20.04,系统语言是目标语言 (hu_HU)
当我使用正确的编码代替 en.po
中的单词 CHARSET
时,代码对我有用 - 即。 UTF-8
"Content-Type: text/plain; charset=UTF-8\n".
顺便说一句:
当我在console/terminal
中使用msgfmt -c en.po -o myapp.mo
然后它甚至显示警告
en.po: warning: Charset "CHARSET" is not a portable encoding name.
Message conversion to user's charset might not work.
并确认 CHARSET
必须更改。
它还显示其他值的警告 - PACKAGE VERSION
、YEAR-MO-DA HO:MI+ZONE
、FULL NAME <EMAIL@ADDRESS>
、LANGUAGE
- 但它们并不那么重要。
po/en.po:7: warning: header field 'Project-Id-Version' still has the initial default value
po/en.po:7: warning: header field 'PO-Revision-Date' still has the initial default value
po/en.po:7: warning: header field 'Last-Translator' still has the initial default value
po/en.po:7: warning: header field 'Language-Team' still has the initial default value
po/en.po:7: warning: header field 'Language' still has the initial default value
编辑:
似乎代码集 LC_ALL
- locale.setlocale(locale.LC_ALL, ...)
但在我的系统中(Linux Mint 19.2 基于 Ubuntu 18.04)我也有 LANG=pl_PL.UTF-8
, LANGUAGE=pl_PL:pl
也许这会有所作为。但是我不能在代码中设置它 locale.setlocale(locale.LANG, ...)
编辑:
您确认变量 LANGUAGE
是问题所在。
如果 LANGUAGE
是 hu:en
或 hu
那么 .mo
文件必须在文件夹 hu
而不是 hu_HU
顺便说一句:
我检查过我在 /usr/share/locale/
中也有文件夹 hu
但是当我 运行
locale -a | grep hu
然后显示给我
hu_HU
hu_HU.UTF-8
和 locale.setlocale(locale.LC_ALL, 'hu')
给我错误,但 locale.setlocale(locale.LC_ALL, 'hu_HU')
运行 没有错误。
我创建了两个包含不同单词 mo/hu_HU/...
和 mo/pl_PL/...
的文件夹,即使我使用 locale.setlocale(locale.LC_ALL, 'hu_HU')
我也会看到来自 pl_PL
的单词。但是当我删除 locale.setlocale()
然后我看到英文单词。
要查看来自 hu_HU
的文字,我必须 运行 在控制台中将其设为
LANGUAGE=hu_HU python test.py