Reputation: 14674
Strings in QObject
s 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.
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.
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))
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 ?
Upvotes: 4
Views: 2939
Reputation: 120608
I think what you're looking for is QT_TR_NOOP (or QT_TRANSLATE_NOOP if you need to provide context).
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).
Thus:
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))
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.
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')
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
Upvotes: 4