PyQt:在运行时翻译模块字符串



QObject s 中的字符串在运行时翻译。如果更改转换器,则会刷新所有这些字符串。但是,在模块级别声明的字符串甚至静态类属性在导入时都会转换。

我可以看到 3 种允许翻译模块字符串的方法,其中一种对我来说似乎都不完全令人满意:

    安装转换器
  • 后导入模块(请参阅此处(段落提前安装转换器))。这可能不方便,但可行,只要在运行时不需要更改语言。

  • 使字符串成为类实例属性。井。。。是的,显然。但这打破了设计。

  • 将字符串保留在模块级别。使用QtCore.QCoreApplication.translate()让 pylupdate 拾取它们。然后在运行时通过调用self.tr()QtCore.QCoreApplication.translate()来翻译它们。例:

    translate = QtCore.QCoreApplication.translate
    strings = [translate('foo'), translate('bar')]
    class my_class(QObject):
        def __init__(self):
            for s in strings:
                print(self.tr(s))
    
    执行此操作时,必须确保在模块导入

    之前不会安装转换器,否则,模块字符串在导入时被翻译(声明中的translate())并在运行时重新翻译(类实例中的 self.tr())。在一般情况下,这不会被看到:self.tr() 将尝试翻译一个已经翻译的字符串,该字符串不太可能存在于原始语言字符串集中,并且它将静默返回字符串本身。

    但是,例如,如果一个英语字符串碰巧翻译成一个法语字符串,该字符串等于

    出现在同一类中的另一个英语字符串,那么将显示该字符串的法语翻译。

有没有一种干净的方法可以做到这一点?

我认为您正在寻找的是QT_TR_NOOP(如果您需要提供上下文,则QT_TRANSLATE_NOOP)。

这会将字符串文字标记为需要翻译(即,以便pylupdate拾取它),但它在运行时(也不导入时)进行任何翻译。

因此:

from PyQt4.QtCore import QT_TR_NOOP
some_string = QT_TR_NOOP('Hello World')
class SomeClass(QObject):
    def do_something(self):
        print(self.tr(some_string))

此处的tr()将在运行时动态转换some_string,但它本身将被pylupdate忽略,因为它不包含字符串文字。

请注意,QT_TR_NOOP可以在 python 中别名tr(或者您可以定义自己的虚拟tr函数),因为pyludate只执行静态分析:

from PyQt4.QtCore import QT_TR_NOOP as tr
some_string = tr('Hello World')

您也可以使用真正的别名(即 trtranslate__tr 等以外的其他名称),方法是使用相应的 pylupdate 选项:

pylupdate -tr-function FOO file.pro

相关内容

最新更新