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')
您也可以使用真正的别名(即 tr
、translate
、__tr
等以外的其他名称),方法是使用相应的 pylupdate
选项:
pylupdate -tr-function FOO file.pro