2015-02-07 116 views
4

我想使用QTranslator来使用英文文本标签,并且软件仍然显示德文标签。PySide Qt tr()不翻译,翻译()确实 - 上下文错误?

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

第一张照片正确地将'Apple2'翻译为'Apfel2'。 Qt Linguist中的上下文也有上下文'app'。 虽然第二次打印不会翻译。类(在相同的python文件中定义)中的调用tr()也不会翻译。

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为类生成的上下文是主窗口:

视图

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(应用程序)解决了我的问题。

回答

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) 
+0

正如我上面写的那样,翻译器正确加载了.qm文件。另外app.translate()正在工作,这只有在正确加载的转换器的情况下才有可能。我也尝试了绝对路径,没有任何改变。 – Josch 2015-02-07 19:37:55

+1

@Josch。你的问题没有真正说清楚,但无论如何,我已经用不同的解释更新了我的答案。 – ekhumoro 2015-02-07 23:54:09

+0

对不起,我认为这是由一个词的工作翻译所隐含的。 我也更新了我的问题。感谢您的支持。 – Josch 2015-02-08 16:05:08

2

如果你来到这里跟我一样,想了解你应该如何使用PySide做翻译。

使用翻译(),不TR()

有关使用tr()恼人的是,你必须手动编辑生成.ts文件每次与他提出的方法编辑源,这种编辑需要花费很多时间,特别是在更新.ts文件时,因为它将所有.tr()调用置于“未知上下文”上下文中,所以必须手动将所有翻译再次移回到正确的上下文中,非常快速地失控。

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

我读the official pyqt4-lupdate documentation,和它说

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

from QtCore import QCoreApplication 
translate = QCoreApplication.translate 

class A(QtCore.QObject): 
    def hello(self): 
     return translate("A", "Hello") 

其中, “A” 是硬编码的情况下,这pyside-lupdate找到。好了很多!

+0

[原始问题](http://stackoverflow.com/revisions/28385477/1)有这样的标题:“PySide Qt tr()不翻译,翻译()做”。具体是关于为什么'tr()'在PySide/PyQt中的行为方式,以及如何避免必须指定上下文。 OP的原始代码示例实际上使用了'app.translate('app','Apple2')',因此您的答案不提供任何新信息。 (PS:你链接到的文档是'pylupdate4',而不是'pyside-lupdate'。但是在任何情况下,我的回答都与这些文档不得不说的内容相矛盾。 – ekhumoro 2016-12-16 20:13:24

+0

PS:我现在已经恢复了以前对这个问题的编辑,所以现在我的答案更有意义。 – ekhumoro 2016-12-16 20:25:51

+2

@ekhumoro好吧,我不知道这是原来的问题。无论如何,我都会在这里留下这个答案,因为如果你想正确翻译,这是一条路。我已经对你的帖子进行了批评。 – Azeirah 2016-12-16 23:47:39