PyQt: переводить строки модуля во время выполнения

Строки в QObjectс переводятся во время выполнения. Если переводчик изменяется, все эти строки обновляются. Однако строки, объявленные на уровне модуля или даже статические атрибуты класса, переводятся во время импорта.

Я вижу 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() будет пытаться перевести уже переведенную строку, которая вряд ли существует в исходном наборе строк языка, и она будет молча возвращать саму строку.

    Но если, например, английская строка преобразуется во французскую строку, которая равна другой английской строке, встречающейся в том же классе, то вместо этого будет отображаться французский перевод этой строки.

Есть ли чистый способ сделать это?

1 ответ

Решение

Я думаю, что вы ищете 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 может быть связан с именем tr в Python (или вы могли бы просто определить свой собственный манекен 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
Другие вопросы по тегам