PySide Qt tr() 不翻译,translate() 翻译 - 上下文错误?

Jos*_*sch 5 python translation qt4 pyside

我想使用 QTranslator 以便能够使用英文文本标签,并且仍然让软件显示德文标签。

不幸的是,我的应用程序不会翻译,除非我指定了上下文。以下静态函数实例化 QApplication 并添加所需的转换器。

第一个打印将“Apple2”正确翻译为“Apfel2”。Qt Linguist 中的上下文也有上下文“app”。不过,第二个印刷品没有翻译。tr()类中的调用(在同一个 python 文件中定义)也不翻译。

def load_application():
    app = QApplication()

    qt_translator = QTranslator()
    qt_translator.load('qt_' + QLocale.system().name(), QLibraryInfo.location(QLibraryInfo.TranslationsPath))
    app.installTranslator(qt_translator)

    app_translator = QTranslator()
    r = app_translator.load('i18n/' + QLocale.system().name())
    app.installTranslator(app_translator)

    print(app.translate('app', 'Apple2'))
    print(app.tr('Apple'))

    return app
Run Code Online (Sandbox Code Playgroud)

编辑:

静态函数的部分是正确的。应用程序的上下文是 QApplication。但这对 QMainWindow 子类没有帮助。我相应地更新了代码。pyside-lupdate 为类生成的上下文是 MainWindow:

看法

class MainWindow(QMainWindow):
    add_model_widget = None

    def __init__(self):
        QMainWindow.__init__(self)

        # Create menu bar
        menu_bar = QMenuBar(self)
        m_file = QMenu(self.tr('File'), menu_bar)
        a_add_model = QAction(QIcon('add.png'), self.tr('Add Jewel'), self)

        m_file.addAction(a_add_model)
        menu_bar.addMenu(m_file)
        self.setMenuBar(menu_bar)

def load_application():
    app = QApplication()

    app_translator = QTranslator()
    app_translator.load(QLocale.system().name(), 'i18n')
    app.installTranslator(app_translator)

    return app
Run Code Online (Sandbox Code Playgroud)

控制器

def initiate():
    model.initiate_mongodb()
    app = view.load_application()

    main_window = view.MainWindow()

    main_window.show()
    sys.exit(app.exec_())
Run Code Online (Sandbox Code Playgroud)

解决方案: 我的问题的解决方案是 QTranslator 没有任何父级。QTranslator(app) 解决了我的问题。

ekh*_*oro 5

之所以会发生这种情况,是因为与 Qt 不同,PySide/PyQt 在运行时确定上下文。

在您的示例中,上下文将(我认为)QApplication在运行时解析为 ,而 pyside/pyqt lupdate 工具会将其硬编码为app. 这些工具只对源代码进行静态分析,因此我认为它们不够聪明,无法找出正确的类应该是什么。

不过,如果您执行以下操作,示例代码应该可以工作:

class App(QtGui.QApplication):
    def __init__(self):
        super(App, self).__init__()
        message = self.tr('Apple')
...
app = App()
...
print(app.tr('Apple'))
Run Code Online (Sandbox Code Playgroud)

(显然您需要首先更新翻译文件)。

编辑

这是一个适合我的简化演示:

测试.py

import sys, os
from PySide import QtCore, QtGui

class MainWindow(QtGui.QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        menu = self.menuBar().addMenu(self.tr('File'))
        menu.addAction(self.tr('Hello World'))

if __name__ == '__main__':

    app = QtGui.QApplication(sys.argv)
    translator = QtCore.QTranslator(app)
    translator.load('i18n/tr_de', os.path.dirname(__file__))
    app.installTranslator(translator)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())
Run Code Online (Sandbox Code Playgroud)

i18n/tr.pro

SOURCES = ../test.py
TRANSLATIONS = tr_de.ts
Run Code Online (Sandbox Code Playgroud)

i18n/tr_de.ts

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS><TS version="1.1" language="de_DE">
<context>
    <name>MainWindow</name>
    <message>
        <location filename="../test.py" line="7"/>
        <source>File</source>
        <translation>Datei</translation>
    </message>
    <message>
        <location filename="../test.py" line="8"/>
        <source>Hello World</source>
        <translation>Hallo Welt</translation>
    </message>
</context>
</TS>
Run Code Online (Sandbox Code Playgroud)

命令输出

$ pyside-lupdate -verbose -noobsolete i18n/tr.pro
Updating 'tr_de.ts'...
    Found 2 source texts (2 new and 0 already existing)
$ lrelease-qt4 i18n/tr.pro
Updating './i18n/tr_de.qm'...
    Generated 2 translation(s) (2 finished and 0 unfinished)
Run Code Online (Sandbox Code Playgroud)


Aze*_*rah 5

如果您像我一样来到这里,想了解应该如何使用 PySide 进行翻译。

使用translate(),而不是tr()

使用的烦人之处tr()在于,每次使用他建议的方法编辑源代码时,您都必须手动编辑生成的 .ts 文件,此编辑需要花费大量时间,尤其是当您更新 .ts 文件时,因为它会将所有 .ts 文件放入其中。 tr() 在“未知上下文”上下文中调用,您必须再次手动将所有翻译移回正确的上下文,这很快就会失控。

相反,有一个非常简单的解决方案。

我阅读了官方 pyqt4-lupdate 文档,它说

PyQt4 的行为并不令人满意,将来可能会改变。建议优先使用 QCoreApplication.translate() 而不是 tr()(和 trUtf8())。这保证可以与当前和未来版本的 PyQt4 配合使用,并使 Python 和 C++ 代码之间共享消息文件变得更加容易。下面是使用 QCoreApplication.translate() 的 A 的替代实现:

from QtCore import QCoreApplication
translate = QCoreApplication.translate

class A(QtCore.QObject):
    def hello(self):
        return translate("A", "Hello")
Run Code Online (Sandbox Code Playgroud)

其中“A”是硬编码上下文,pyside-lupdate 找到。好了很多!

  • @ekhumoro 好吧,我不知道这是原来的问题。无论如何,我都会把这个答案留在这里,因为如果你想正确地进行翻译,这是要走的路。我已经删除了对您帖子的批评。 (2认同)