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

时间:2015-02-07 17:55:28

标签: python qt4 translation 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

修改

静态功能的部分是正确的。该应用程序的上下文是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

控制器

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

    main_window = view.MainWindow()

    main_window.show()
    sys.exit(app.exec_())

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

2 个答案:

答案 0 :(得分:3)

这似乎发生了,因为与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'))

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

修改

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

<强> test.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_())

<强> I18N / tr.pro

SOURCES = ../test.py
TRANSLATIONS = tr_de.ts

<强> 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>

命令输出

$ 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)

答案 1 :(得分:2)

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

使用translate(),而非 tr()

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

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

我看了the official pyqt4-lupdate documentation,并说

  

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")

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