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

时间:2015-03-13 14:48:51

标签: qt4 pyqt4 translation

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

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

  • 安装翻译器后导入模块(请参阅here(段落早期安装翻译器))。这可能不方便但是可行,只要不需要在运行时更改语言。

  • 创建字符串类实例属性。嗯......是的,很明显。但这打破了设计。

  • 将字符串保持在模块级别。使用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()将尝试翻译原始语言字符串集中可能不存在的已翻译字符串,并且它将以静默方式返回字符串本身。

    但是,例如,如果英语字符串碰巧转换为法语字符串,该字符串等于出现在同一个类中的另一个英语字符串,则会显示该字符串的法语翻译。

这样做有干净的方法吗?

1 个答案:

答案 0 :(得分:3)

我认为您正在寻找的是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')

您还可以使用相应的tr选项使用真正的别名(即translate__trpylupdate以外的其他内容):

pylupdate -tr-function FOO file.pro