有没有一种方法可以避免键入QCoreApplication.translate(“ Context” ,?

时间:2020-08-31 11:36:42

标签: python translation pyside2

要在PySide2应用程序中翻译字符串,我需要调用QCoreApplication.translate()并指定一个上下文,其中包含许多字符来翻译短字符串。 即:QCoreApplication.translate("MyClassName", "Hello") 我试图做这样的事情:

from PySide2.QtCore import QCoreApplication
from functools import partial


class Translate:
    def __init__(self, context):
        self.context = context
        self.translate = partial(QCoreApplication.translate, self.context)

    def __call__(self, text):
        return self.translate(text)

这种方式QCoreApplication.translate()是在正确的上下文中调用的,在我的资料中,我可以使用一个较短的名称,但是未提取字符串并将其存储在* .ts文件中。 有没有办法至少减少翻译用python编写的Qt软件所需的样板字符数量?也许通过配置pyside2-lupdate?

3 个答案:

答案 0 :(得分:0)

如果您使用的是类,则从QObject继承可以为您提供self.tr("your text")方法,该方法将具有适当的上下文。

QCoreApplication.translate()替换QObject().tr("your string")确实可以,但是假设您每次翻译字符串时都创建一个新的QObject ...

在全局范围内tr = QObject().tr似乎也可以工作(我怀疑这会很快变得棘手)。

答案 1 :(得分:0)

我想到的是这个非常简单的功能:

defaultContext = "MyClassName"

def translate(str, context=defaultContext):
    return QCoreApplication.translate(context, str)

在定义函数时可以指定默认上下文,也可以通过将defaultContext设置为其他值来随时全局更改它。您可以选择在每个调用中传递不同的上下文,但是默认调用是超级简单和干净的:

translated = translate("Hello")

或者我想念什么吗?

答案 2 :(得分:0)

首先感谢 benjamin-forestCryptoFool,他们的回答很有用。

我发现这里实际上存在三个不同的问题:

  • 自定义函数仅由来自 PyQt5 的 pylupdate5 支持,
    pyside2-lupdate 没有配置选项,不像 lupdate
  • pylupdate5pyside2-lupdate 在使用全局函数时都无法猜测上下文,因此它们读取的每个字符串都会转到 @default 上下文
  • 如官方 PyQt 文档中所述,self.tr() 的默认实现在运行时获取其上下文

Differences Between PyQt5 and Qt

<块引用>

Qt 通过 QTranslator 实现国际化支持 类,以及 translate()tr() 方法。通常 tr() 用于 获得消息的正确翻译。翻译过程 使用消息上下文来允许翻译相同的消息 不同。在 Qt 中,tr() 实际上是由 moc 生成并使用 硬编码的类名作为上下文。另一方面,翻译 允许明确指定上下文。

不幸的是,由于 Qt 实现 tr() 的方式,它不是 PyQt5 可能完全重现其行为。 PyQt5 tr() 的实现使用实例的类名作为 语境。关键区别和潜在问题的根源在于 上下文是在 PyQt5 中动态确定的,但是是硬编码的 在 Qt 中。 换句话说,翻译的上下文可能会改变 取决于实例的类层次结构。

我的解决方案是声明一个私有的 __tr() 方法来包装 QCoreApplication.translate()

def __tr(self, txt, disambiguation=None, n=-1):
    return QCoreApplication.translate("TestWidget", txt, disambiguation, n)

并配置 pylupdate5 以在从 setup.py 调用时查找它:

if has_build_ui:
    class build_res(build_ui):
        """Build UI, resources and translations."""

        def run(self):
            # build translations
            check_call(["pylupdate5", "-tr-function", "__tr", "app.pro"])

            lrelease = os.environ.get("LRELEASE_BIN")
            if not lrelease:
                lrelease = "lrelease"

            check_call([lrelease, "app.pro"])

            # build UI & resources
            build_ui.run(self)
            # create __init__ file for compiled ui
            open("app/ui/__init__.py", "a").close()

    cmdclass["build_res"] = build_res

这样一来,pylupdate5 在生成 .ts 文件时都会获得正确的上下文,而 self.__tr() 在运行时始终具有正确的上下文。