Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I wonder if it is possible to change the languages(translations) dynamically without using qt designer to make the UI? That means I don't want to use the function retranslateUi() to update the program interface.

Here is my code, but I'm stuck on lines marked #1 #2 #3. Don't know what I should use to update the interface.

import sys
from PyQt5.QtCore import Qt, QTranslator
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLabel, 
QComboBox, QVBoxLayout
class Demo(QWidget):
    def __init__(self):
        super(Demo, self).__init__()
        self.button = QPushButton(self.tr('Start'), self)
        self.label = QLabel(self.tr('Hello, World'), self)
        self.label.setAlignment(Qt.AlignCenter)
        self.combo = QComboBox(self)
        self.combo.addItem('English')
        self.combo.addItem('中文')
        self.combo.addItem('français')
        self.combo.currentTextChanged.connect(self.change_func)
        self.trans = QTranslator(self)
        self.v_layout = QVBoxLayout()
        self.v_layout.addWidget(self.combo)
        self.v_layout.addWidget(self.button)
        self.v_layout.addWidget(self.label)
        self.setLayout(self.v_layout)
    def change_func(self):
        print(self.combo.currentText())
        if self.combo.currentText() == '中文':
            self.trans.load('eng-chs')
            _app = QApplication.instance()
            _app.installTranslator(self.trans)
        elif self.combo.currentText() == 'français':
            self.trans.load('eng-fr')
            _app = QApplication.instance()
            _app.installTranslator(self.trans)
        else:
            _app = QApplication.instance()
            _app.removeTranslator(self.trans) 
if __name__ == '__main__':
    app = QApplication(sys.argv)
    demo = Demo()
    demo.show()
    sys.exit(app.exec_())

Any help would be appreciated.

TL; DR; It is not necessary to use Qt Designer

You should not use Qt Designer necessarily but you should use the same technique, that is, create a method that could be called retranslateUi() and in it set the texts using translate() instead of tr() (for more details read the docs). Calling that method when you change language for it must use the changeEvent() event. For example in your case the code is as follows:

import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class Demo(QtWidgets.QWidget):
    def __init__(self):
        super(Demo, self).__init__()
        self.button = QtWidgets.QPushButton()
        self.label = QtWidgets.QLabel(alignment=QtCore.Qt.AlignCenter)
        self.combo = QtWidgets.QComboBox(self)
        self.combo.currentIndexChanged.connect(self.change_func)
        self.trans = QtCore.QTranslator(self)
        self.v_layout = QtWidgets.QVBoxLayout(self)
        self.v_layout.addWidget(self.combo)
        self.v_layout.addWidget(self.button)
        self.v_layout.addWidget(self.label)
        options = ([('English', ''), ('français', 'eng-fr' ), ('中文', 'eng-chs'), ])
        for i, (text, lang) in enumerate(options):
            self.combo.addItem(text)
            self.combo.setItemData(i, lang)
        self.retranslateUi()
    @QtCore.pyqtSlot(int)
    def change_func(self, index):
        data = self.combo.itemData(index)
        if data:
            self.trans.load(data)
            QtWidgets.QApplication.instance().installTranslator(self.trans)
        else:
            QtWidgets.QApplication.instance().removeTranslator(self.trans)
    def changeEvent(self, event):
        if event.type() == QtCore.QEvent.LanguageChange:
            self.retranslateUi()
        super(Demo, self).changeEvent(event)
    def retranslateUi(self):
        self.button.setText(QtWidgets.QApplication.translate('Demo', 'Start'))
        self.label.setText(QtWidgets.QApplication.translate('Demo', 'Hello, World'))
if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    demo = Demo()
    demo.show()
    sys.exit(app.exec_())

Then generate the .ts:

pylupdate5 main.py  -ts eng-chs.ts
pylupdate5 main.py  -ts eng-fr.ts

Then use Qt Linguist to do the translations.

And finally the .qm:

lrelease eng-fr.ts eng-chs.qm
                @Jalkhov The big question is what does it mean: lrelease command dont work for me, please be more detailed.
– eyllanesc
                Apr 14, 2021 at 2:17
                Ok, sorry. When I try to use it I get lrelease not recognized as an internal or external command, program or executable batch file.
– Jalkhov
                Apr 14, 2021 at 2:19
                @Jalkhov That error indicates that the lrelease program does not exist so you have to install it and you have 2 options: 1) Install qt or 2) install qt5-applications and replace lrelease with qt5-tools lrelease
– eyllanesc
                Apr 14, 2021 at 2:49
                And what if I have several other widgets connected to the main one? Should I take care myself of calling retranslateUi() for each widget?
–  GhostKU 
                Oct 16, 2022 at 7:08

No you will have to use a technique like Qt Designer does with retranslateUi because the Qt widget system does not have a way to redo the translation on it's own (otherwise QT Designer would be using that to).

Building such a system would require a fundamental change to the widgets as for each string property you would need to know that it contains a translatable string (not a data value) and knowing the original string for looking up the new translation would be best (reversing translations could be ambiguous).

so that means I have to use qt designer to make the UI and call retranslateUi() in my logical codes when I want to change the language? No other way? – just_be_happy Nov 17, 2018 at 13:32

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.