Adding Multilingual (Internationalization) Support to PyQt Apps

PyQt ships with everything you need to provide multiple UI languages.

All examples here use PyQt5.

Flag strings that need translation

Wrap every user-facing string with QObject.tr():

1
2
3
4
5
class Mwindow(QtWidgets.QDialog):
def __init__(self):
super(Mwindow, self).__init__()
self.resize(100, 60)
self.down1 = QtWidgets.QPushButton(self.tr(u'下载'), self)

Because most widgets inherit from QObject, you can call self.tr() directly.

PyQt5 discourages tr() in favor of translate():

1
2
3
class A(QObject):
def hello(self):
return QCoreApplication.translate('A', "Hello")

If you rely on Qt Designer and all of your text lives in the .ui file, life is even easier. Make sure the widgets keep the default “translatable” flag turned on in the text property. When you run pyuic, it wraps the strings with translate() automatically.

Generate and edit the translation file

Create a translation file from the Python module that contains your strings:

pylupdate5 main_ui.py -ts zh_CN.ts

(PyQt4 uses pylupdate4.)

Edit with Linguist

Open the generated file with linguist, which comes with PyQt or pyqt5-tools. Translate each entry and choose “File → Release” to produce the .qm file.

Edit manually

No Linguist? A .ts file is just XML, so you can edit it by hand.

Before translation:

1
2
3
4
<message encoding="UTF-8">
<location filename="GitHub/pdfdir/gui/main_ui.py" line="90"/>
<source>打开</source>
<translation type="unfinished"></translation>

After translation:

1
2
3
4
<message utf8="true">
<location filename="main_ui.py" line="90"/>
<source>打开</source>
<translation>Open</translation>

Once you finish editing, convert the .ts file into .qm with lrelease:

lrelease en.ts

lrelease lives in the PyQt4 directory or ships with pyqt5-tools.

Load the .qm and switch languages

Finally, load the compiled translation file.

Switch at startup

If you detect the system locale first, load the translator before showing the UI:

1
2
3
4
5
6
7
8
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
trans = QtCore.QTranslator()
trans.load("./gui/en.qm")
app.installTranslator(trans)
window = Main(app, trans)
window.show()
sys.exit(app.exec_())

Call installTranslator before show() runs.

Switch on the fly

To change languages at runtime—say, when english_action triggers—reload the translator and retranslate the UI:

1
2
3
4
def to_english(self):
self.trans.load("en.qm")
self.app.installTranslator(self.trans)
self.retranslateUi(self)

retranslateUi is generated by pyuic and looks like this:

1
2
3
def retranslateUi(self, MainUI):
_translate = QtCore.QCoreApplication.translate
self.open_button.setText(_translate("MainUI", "打开"))

If you do not use Qt Designer, create a similar helper that updates every label manually.

References:

  1. How to create a multi language application
  2. Hello tr() Example
  3. Internationalisation of PyQt5 Applications
  4. PyQt internationalization support
  5. Qt multilingual support