PyQt:在运行时翻译模块字符串
PyQt: translate module strings at runtime
QObject
中的字符串在 运行 时翻译。如果翻译器发生变化,所有这些字符串都会被刷新。但是,在模块级别甚至静态 class 属性声明的字符串在导入时被翻译。
我可以看到 3 种允许翻译模块字符串的方法,none 我似乎完全满意:
在安装翻译器后导入模块(参见here(段落提前安装翻译器))。这可能不方便但可行,只要不需要在 运行 时间更改语言。
使字符串成为class实例属性。嗯……是的,很明显。但这破坏了设计。
将字符串保留在模块级别。使用 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() 在 class 实例中)。在一般情况下,这不会被看到:self.tr() 将尝试翻译一个已翻译的字符串,该字符串不太可能存在于原始语言字符串集中,它会静默 return 字符串本身。
但是,例如,如果一个英文字符串恰好翻译成法语字符串,而该字符串与出现在同一 class 中的另一个英文字符串相同,则将显示该字符串的法语翻译。
有没有一种干净的方法可以做到这一点?
我想你要找的是 QT_TR_NOOP (or 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')
您还可以使用相应的 pylupdate
选项来使用真正的别名(即 tr
、translate
、__tr
等以外的别名:
pylupdate -tr-function FOO file.pro
QObject
中的字符串在 运行 时翻译。如果翻译器发生变化,所有这些字符串都会被刷新。但是,在模块级别甚至静态 class 属性声明的字符串在导入时被翻译。
我可以看到 3 种允许翻译模块字符串的方法,none 我似乎完全满意:
在安装翻译器后导入模块(参见here(段落提前安装翻译器))。这可能不方便但可行,只要不需要在 运行 时间更改语言。
使字符串成为class实例属性。嗯……是的,很明显。但这破坏了设计。
将字符串保留在模块级别。使用
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() 在 class 实例中)。在一般情况下,这不会被看到:self.tr() 将尝试翻译一个已翻译的字符串,该字符串不太可能存在于原始语言字符串集中,它会静默 return 字符串本身。
但是,例如,如果一个英文字符串恰好翻译成法语字符串,而该字符串与出现在同一 class 中的另一个英文字符串相同,则将显示该字符串的法语翻译。
有没有一种干净的方法可以做到这一点?
我想你要找的是 QT_TR_NOOP (or 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')
您还可以使用相应的 pylupdate
选项来使用真正的别名(即 tr
、translate
、__tr
等以外的别名:
pylupdate -tr-function FOO file.pro