Qt4 PyQt:在运行时转换模块字符串

Qt4 PyQt:在运行时转换模块字符串,qt4,pyqt4,translation,Qt4,Pyqt4,Translation,QObjects中的字符串在运行时转换。如果转换器已更改,则所有这些字符串都将刷新。但是,在模块级声明的字符串,甚至静态类属性,都在导入时转换 我可以看到3种允许翻译模块字符串的方法,但没有一种能让我完全满意: 安装转换器后导入模块(请参阅(段落Install translator early))。这可能并不方便,但却是可行的,只要不需要在运行时更改语言 使字符串类成为实例属性。好。。。是的,很明显。但这打破了设计 将字符串保持在模块级别。使用QtCore.QCoreApplication.t

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

我可以看到3种允许翻译模块字符串的方法,但没有一种能让我完全满意:

  • 安装转换器后导入模块(请参阅(段落Install translator early))。这可能并不方便,但却是可行的,只要不需要在运行时更改语言

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

  • 将字符串保持在模块级别。使用
    QtCore.QCoreApplication.translate()
    让更新获取它们。然后(再次)在运行时对它们调用
    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()将尝试翻译原始语言字符串集中不太可能存在的已翻译字符串,并将静默返回字符串本身

    但是,例如,如果一个英语字符串恰好翻译成一个法语字符串,该字符串等于同一类中出现的另一个英语字符串,那么将显示该字符串的法语翻译


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

我认为您需要的是(或者如果您需要提供上下文)

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

因此:

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

请注意,
QT\u TR\u NOOP
可以在python中别名为
TR
(或者您可以定义自己的伪
TR
函数),因为
pyludate
只执行静态分析:

from PyQt4.QtCore import QT_TR_NOOP as tr

some_string = tr('Hello World')
您还可以通过使用相应的
更新
选项来使用真实别名(即除
tr
翻译
\uu tr
以外的别名):

pylupdate -tr-function FOO file.pro

再次感谢你,埃克胡洛。我现在不能测试,但你是对的。就是这样。我已经为此挣扎了一段时间,但已经走到了死胡同。很高兴我问了。当我使用
QT\u TR\u NOOP
时,字符串出现在
.ts
文件的上下文
@default
中,我不知道如何在运行时使用它。因此,我使用
ST_TRANSLATE\u NOOP
,指定一个上下文(任何字符串),然后在调用
runtime QtCore.QCoreApplication.TRANSLATE
,指定与上下文相同的字符串。
pylupdate -tr-function FOO file.pro