Python - Switch translations dynamically in a PyQt4 application
<p>I want to add a feature in my program. The user should be able to switch/change the language at runtime - without restart. Imagine the UI displays in English and he wants to switch in German.</p>

<p>Well, I wrote a small example - can't be executed, because you have missing some translation-files and ui-files. But I need your help - for logical. Here is my current code.</p>

<pre><code>import sys
from PyQt4.uic import loadUi
from PyQt4.QtCore import Qt, QFile, QMetaObject
from PyQt4 import QtCore
from PyQt4.QtGui import QMainWindow, QApplication

class Test_Window(QMainWindow):
    def __init__(self,
                 app):
        QMainWindow.__init__(self, parent=None)

        UI_PATH = QFile("testlangs.ui")

    # save reference to app for later
        self._app = app

        # Load ui dynamically
        UI_PATH.open(QFile.ReadOnly)
        self.ui = loadUi(UI_PATH, self)
        UI_PATH.close()

        self.init_current_language()
        self.init_connect_menu_item()


    def init_current_language(self):
        self.current_translator = QtCore.QTranslator(self._app)
        self.current_translator.load("langs_en")
        self._app.installTranslator(self.current_translator)


    def init_connect_menu_item(self):
        self.actionDeutsch.triggered.connect(lambda: self.change_language("langs_de"))
        self.actionEnglish.triggered.connect(lambda: self.change_language("langs_en"))


    # Change the language to German
    def change_language(self, language):
        self._app.removeTranslator(self.current_translator)
        self.current_translator = QtCore.QTranslator(self._app)
        self.current_translator.load(language)
        self._app.installTranslator(self.current_translator)
        self.retranslateUi(self.ui)
</code></pre>

<p>Now, I have some problem:</p>

<p>First of all: I can't call and execute the <strong>retranslateUi()</strong>-method. The "problem" is I load the ui-file at runtime dynamically. And this method is a part of generated ui-file. That means, the ui-file is converted in py-file. And there you will finde the <strong>retranslateUi()</strong>-method.</p>

<p>What can i do?</p>

<p>Simple and dirty way looks like:</p>

<pre><code>def retranslateUi(self, MainWindow):
    MainWindow.setWindowTitle(self._app.translate("MainWindow", "MainWindow", None, self._app.UnicodeUTF8))
    self.nameLabel.setText(self._app.translate("MainWindow", "Name", None, self._app.UnicodeUTF8))
    self.ageLabel.setText(self._app.translate("MainWindow", "Age", None, self._app.UnicodeUTF8))
    self.menuMenu.setTitle(self._app.translate("MainWindow", "File", None, self._app.UnicodeUTF8))
    self.menuEdit.setTitle(self._app.translate("MainWindow", "Edit", None, self._app.UnicodeUTF8))
    self.menuLanguage.setTitle(self._app.translate("MainWindow", "Language", None, self._app.UnicodeUTF8))
    self.actionOpen.setText(self._app.translate("MainWindow", "Open", None, self._app.UnicodeUTF8))
    self.actionSave.setText(self._app.translate("MainWindow", "Save", None, self._app.UnicodeUTF8))
    self.actionClear.setText(self._app.translate("MainWindow", "Clear", None, self._app.UnicodeUTF8))
    self.actionEnglish.setText(self._app.translate("MainWindow", "English", None, self._app.UnicodeUTF8))
    self.actionDeutsch.setText(self._app.translate("MainWindow", "Deutsch", None, self._app.UnicodeUTF8))
</code></pre>

<p>I re-implement the missing method by copying this method from a generated ui. This dirty way works fine, but I think this isn't elegant solution.</p>

<p>There a any other and elegant ways to solve it? </p>

<p>Use <a href="http://pyqt.sourceforge.net/Docs/PyQt4/designer.html#PyQt4.uic.loadUiType" rel="nofollow">loadUiType</a> to load the ui file, which will give you the base-class and the ui-class needed for creating a subclass. As with your previous approach, this will result in all the child widgets becoming attributes of the main window, and you will also be able to call <code>self.retranslateUi(self)</code>:</p>

<pre><code>from PyQt4.uic import loadUiType

UiClass, BaseClass = loadUiType('testlangs.ui')

class Test_Window(BaseClass, UiClass):
    def __init__(self, app):
        super(Test_Window, self).__init__(parent=None)

        self.setupUi(self)

        # save reference to app for later
        self._app = app

        self.init_current_language()
        self.init_connect_menu_item()
</code></pre>

python pyqt4 translation