PyQt:在运行时翻译模块字符串 [英] PyQt: translate module strings at runtime

查看:60
本文介绍了PyQt:在运行时翻译模块字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

QObject 中的字符串在运行时被翻译.如果翻译器发生变化,所有这些字符串都会被刷新.但是,在模块级别声明的字符串甚至静态类属性会在导入时进行翻译.

Strings in QObjects are translated at runtime. If the translator is changed, all those strings are refreshed. However, strings declared at module level or even static class attributes, are translated at import time.

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

I can see 3 ways of allowing module strings to be translated, none of which seems totally satisfying to me :

  • 在安装翻译器后导入模块(见此处(段落尽早安装翻译器)).这可能不太方便但可行,只要不需要在运行时更改语言即可.

  • Import the module after the translator is installed (see here (paragraph Install translator early)). This may not be handy but is feasible, as long as one doesn't need to change language at runtime.

使字符串类实例属性.嗯……是的,很明显.但这破坏了设计.

Make the strings class instance attributes. Well... yes, obviously. But this breaks the design.

将字符串保持在模块级别.使用 QtCore.QCoreApplication.translate() 让它们被 pylupdate 接收.然后在运行时通过对它们调用 self.tr()QtCore.QCoreApplication.translate() 来翻译它们(再次).示例:

Keep the strings at module level. Use QtCore.QCoreApplication.translate() to let them be picked up by pylupdate. Then translate them (again) at runtime by calling self.tr() or QtCore.QCoreApplication.translate() on them. Example :

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() 将尝试翻译一个已经翻译的字符串,该字符串在原始语言字符串集中不太可能存在,并且它会默默地返回字符串本身.

When doing this, one must ensure that no translator will be installed before module import, otherwise, the module strings are translated at import time (translate() in declaration) and retranslated at run time (self.tr() in class instance). In the general case this won't be seen: self.tr() will try to translate an already translated string which is not likely to exist in the original language string set, and it will silently return the string itself.

但是,例如,如果一个英文字符串碰巧翻译成一个法语字符串,该字符串与出现在同一类中的另一个英语字符串相等,那么将显示该字符串的法语翻译.

But if for instance an English string happens to translates into a French string that is equal to another English string appearing in the same class, then the French translation of this string will be displayed instead.

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

Is there a clean way of doing this ?

推荐答案

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

I think what you're looking for is QT_TR_NOOP (or QT_TRANSLATE_NOOP if you need to provide context).

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

This will mark a string literal as needing translation (i.e. so that it is picked up by pylupdate), but it does not do any translation at runtime (nor import time).

因此:

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 忽略,因为它不包含字符串文字.

The tr() here will translate some_string dynamically at runtime, but it will itself be ignored by pylupdate because it does not contain a string literal.

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

Note that QT_TR_NOOP could be aliased to the name tr in python (or you could just define your own dummy tr function), because pyludate only ever does static analysis:

from PyQt4.QtCore import QT_TR_NOOP as tr

some_string = tr('Hello World')

您也可以使用真正的别名(即除了 trtranslate__tr 等),通过使用相应的 <代码>pylupdate 选项:

You can also use a true alias (i.e. something other than tr, translate, __tr, etc), by using the corresponding pylupdate option:

pylupdate -tr-function FOO file.pro

这篇关于PyQt:在运行时翻译模块字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆