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) 解决了我的问题。
之所以会发生这种情况,是因为与 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)
如果您像我一样来到这里,想了解应该如何使用 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 将找到。好了很多!