9、Translating Applications

Qt Linguist

Qt Linguist 及其相关工具可用于为应用程序提供翻译。

示例/小部件/语言学家示例说明了这一点。这个例子非常简单,它有一个菜单,并显示了一个具有多选功能的编程语言列表。

翻译的工作原理是通过查找翻译的函数调用传递消息字符串。每个 QObject 实例为此目的提供一个 tr() 函数。还有用于将翻译文本添加到非 QObject 类的 QCoreApplication.translate()。

Qt 提供了它自己的包含错误消息和标准对话框标题的翻译。

语言学家的例子有一些包含在 self.tr() 中的消息。响应选择更改而显示的状态栏消息根据计数使用复数形式:

count = len(self._list_widget.selectionModel().selectedRows())
message = self.tr("%n language(s) selected", "", count)

该示例的翻译工作流程如下:使用 lupdate 工具提取翻译后的消息,生成基于 XML 的 .ts 文件:

pyside6-lupdate main.py -ts example_de.ts

如果 example_de.ts 已经存在,它将使用添加到中间代码中的新消息进行更新。 如果项目中有表单文件(.ui)和/或 QML 文件(.qml),它们也应该传递给 pyside6-lupdate 工具:

mkdir translations
pyside6-lrelease example_de.ts -qm translations/example_de.qm

为避免发送 .qm 文件,建议将它们与图标和其他应用程序资源一起放入 Qt 资源文件中(请参阅使用 .qrc 文件 (pyside6-rcc))。资源文件 linguist.qrc 在 :/translations 下提供了 example_de.qm:

<!DOCTYPE RCC><RCC version="1.0">
<qresource>
    <file>translations/example_de.qm</file>
</qresource>
</RCC>

在运行时,需要使用 QTranslator 类加载翻译:

path = QLibraryInfo.location(QLibraryInfo.TranslationsPath)
translator = QTranslator(app)
if translator.load(QLocale.system(), 'qtbase', '_', path):
    app.installTranslator(translator)
translator = QTranslator(app)
path = ':/translations'
if translator.load(QLocale.system(), 'example', '_', path):
    app.installTranslator(translator)

代码首先加载为 Qt 提供的翻译,然后加载从资源中加载的应用程序的翻译。

然后可以用德语运行该示例:

LANG=de python main.py

GNU gettext

GNU gettext 模块可用于为应用程序提供翻译。

examples/widgets/gettext 示例说明了这一点。这个例子非常简单,它有一个菜单,并显示了一个具有多选功能的编程语言列表。

翻译的工作原理是通过查找翻译的函数调用传递消息字符串。通常将主翻译函数别名为_。对于包含复数形式的句子有一个特殊的翻译功能,具体取决于计数(“{0} items(s) selected”)。它通常别名为 ngettext。

这些函数在顶部定义:

import gettext
...
_ = None
ngettext = None

后来分配如下:

src_dir = Path(__file__).resolve().parent
try:
    translation = gettext.translation('example', localedir=src_dir / 'locales')
    if translation:
        translation.install()
        _ = translation.gettext
        ngettext = translation.ngettext
except FileNotFoundError:
    pass
if not _:
    _ = gettext.gettext
    ngettext = gettext.ngettext

这指定我们的翻译文件具有基本名称 example 并将在语言环境下的源树中找到。该代码将尝试加载与当前语言匹配的翻译。

要翻译的消息如下所示:

file_menu = self.menuBar().addMenu(_("&File"))

响应选择更改而显示的状态栏消息根据计数使用复数形式:

count = len(self._list_widget.selectionModel().selectedRows())
message = ngettext("{0} language selected",
                   "{0} languages selected", count).format(count)

该文件有一些通用占位符,可以用适当的值替换。然后将其复制到 de_DE/LC_MESSAGES 目录。

cd locales/de_DE/LC_MESSAGES/
cp ../../example.pot .

需要进一步调整以解释德语复数形式和编码:

"Project-Id-Version: PySide6 gettext example\n"
"POT-Creation-Date: 2021-07-05 14:16+0200\n"
"Language: de_DE\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"

下面,可以给出翻译后的消息:

#: main.py:57
msgid "&File"
msgstr "&Datei"

最后,.pot 被转换成它的二进制形式(机器目标文件,.mo),它需要被部署:

msgfmt -o example.mo example.pot

然后可以用德语运行该示例:

LANG=de python main.py

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值