2015-02-07 89 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