0
点赞
收藏
分享

微信扫一扫

PySide6:程序的翻译

Qt Linguist

Qt Linguist是解决字符串​乱码​​和翻译的问题,实现Qt国际化的工具。

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

​examples/widgets/linguist​​示例说明了这一点。这个例子很简单,它有一个菜单,并显示了一系列多选的编程语言。

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

Qt发布了自己的翻译,其中包含错误消息和标准对话框标题。

linguist 的例子中有许多消息包含在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​​工具:

pyside6-lupdate main.py main.qml form.ui -ts example_de.ts

用​​pyside6-uic​​从表单文件生成的源文件不应该被传递。

.ts文件使用Qt Linguist进行翻译。完成此操作后,文件将转换为二进制格式(.qm文件):

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

为了避免不得不发布.qm文件,建议将它们与图标和其他应用程序资源一起放入Qt资源文件中(请参见使用.qrc文件(pyside6 rcc))。资源文件语言学家。qrc提供了examplede。qm位于:/translations:

<!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}选择的项目”),有一个特殊的翻译功能。它通常别名为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

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

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

要翻译的消息如下:

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

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

ngettext()函数采用单数形式、复数形式和计数。返回的字符串仍然包含格式化占位符,因此需要通过format()传递。

为了将消息转换为德语,首先创建一个模板文件(.pot):

mkdir -p locales/de_DE/LC_MESSAGES
xgettext -L Python -o locales/example.pot main.py

此文件有一些通用占位符,可以用适当的值替换。然后将其复制到​​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

可以参考下面的文章:

​​https://blog.csdn.net/lvdepeng123/article/details/90719769​​


举报

相关推荐

0 条评论