I'm creating a multilanguage desktop app using Qt Designer and PyQt5. I'm following this answer to make my app change languages dynamically.
I've created a .ui file via Qt Designer and I'm loading the UI directly in python code via loadUi. Therefore, the function retranslateUi is described in my ui.file unlike the retranslateUi function in link above (it is present in python code). I wouldn't like to put the described function in python code because there's a lot buttons and labels. How can I use this function in my code and to keep it only in .ui file?
If you use the loadUi method it doesn't implement the retranslateUi method so if you use that method then the solution is the same as the previous post.
demo.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Demo</class>
<widget class="QWidget" name="Demo">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>102</width>
<height>108</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QComboBox" name="combo"/>
</item>
<item>
<widget class="QPushButton" name="button">
<property name="text">
<string>Start</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Hello, World</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
main.py
import sys
from PyQt5 import QtCore, QtGui, QtWidgets, uic
class Demo(QtWidgets.QWidget):
def __init__(self):
super(Demo, self).__init__()
uic.loadUi("demo.ui", self)
self.combo.currentIndexChanged.connect(self.change_func)
self.trans = QtCore.QTranslator(self)
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-fr.qm
lrelease eng-chs.ts eng-chs.qm
On the other hand, if you are using pyuic5 to convert the .py then if the retranslateUi method is implemented so you can use it:
pyuic5 demo.ui -o demo_ui.py
pylupdate5 demo_ui.py -ts eng-chs.ts
pylupdate5 demo_ui.py -ts eng-fr.ts
Then use Qt Linguist to do the translations.
And finally the .qm:
lrelease eng-fr.ts eng-fr.qm
lrelease eng-chs.ts eng-chs.qm
main.py
import sys
from PyQt5 import QtCore, QtGui, QtWidgets, uic
from demo_ui import Ui_Demo
class Demo(QtWidgets.QWidget, Ui_Demo):
def __init__(self):
super(Demo, self).__init__()
self.setupUi(self)
self.combo.currentIndexChanged.connect(self.change_func)
self.trans = QtCore.QTranslator(self)
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(self)
@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(self)
super(Demo, self).changeEvent(event)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
demo = Demo()
demo.show()
sys.exit(app.exec_())