The translation of an application is usually a fastidious and painful process.
Hopefully, Qt provides excellent support for translating into local language applications developed in C++ or Python.
Qt lets you load language translation files into an application at run-time. This means that application texts (i.e., menus, screen titles, field labels, help files, etc.) are displayed in the local language.
Qt uses its QString class exclusively to manage the strings. This comprehensive class handles Unicode, the world standard for Text and Emoji, natively.
In this article, I will explain the translation process step-by-step. However, I will not go through the tool’s details because Qt provides excellent documentation and many tutorials are available on the Web.
Apart from Python interpreter and your favorite Python IDE, you will have to install the qt package. Qt includes a comprehensive set of tools like pylupdate5, lrelease and pyrcc5 for translating applications into local languages. I will come back to these tools below.
Remark: Although it’s not the subject of this article, I strongly recommend you to use virtual environments (virtualenv or anaconda) for project development. This is one of the essential tools that most of the Python developers use.
You will find hereunder a schema showing the translation process:
Depending on the type and the size of a project, the developer and the translator can be one unique person.
For the creation of the application’s GUI part, there are two options for the developer:
- Use Qt Designer, a tool for designing and building graphical user interfaces with Qt Widgets. The Widgets and forms created with Qt Designer can be integrated seamlessly with programmed code. Furthermore, all the properties which are set in Qt Designer can be changed dynamically within the application code.
- Use the Python modules provided by Qt to implement and configure the widgets into the application code manually.
You will find hereunder a quick overview of the process steps:
- Step 1 (optional): Design and build the GUI part with Qt Designer.
- Step 2 (optional): Convert the Qt Designer’s files into python files.
- Step 3: Implement the code needed for the translation process.
- Step 4: Creation or update of the translation files.
- Step 5: Translation of the texts.
- Step 6: Convert translation files into binary files.
- Step 7 (optional): Convert the translation binary files into a python resources module.
Preparation of the Python application code
GUI code generated by Qt Designer
If the developer uses the Qt Designer tool to build the GUI, he must first convert the Qt source file (.ui) into a Python source file (.py). This conversion is performed by executing the pyuic5 tool (step 2). I recommend using a batch file for this. Here is an example:
Pyuic5 tool automatically adds at the end of the python file a function dedicated to the translation. This function translates all the strings found in the Qt source file by using the Qt translate function. So the developer doesn’t need to perform additional action regarding the texts:
GUI code generated manually
- If the developer builds the GUI manually, he must prepare the code by calling the Qt translate function for each string which requires translation (step 3). To make the code more readable, I recommend you to implement the following tr() function:
Then, the developer just has to call the
tr() function for each text to be translated:
Translation Files (.ts)
The translation files (.ts) must be either created if not existing or updated if a text has been added, modified, or removed. The developer has to use a specific file (.pro) to configure how the translation files will be generated:
- SOURCES: Python source files containing the texts to translate
- TRANSLATIONS: Language files. The file’s name is composed of the application name followed by the language and, finally, the .ts extension. See the next chapter for additional information regarding the language.
The developer has to use the pylupdate5 Qt tool to generate the translation files:
The execution of this batch file will automatically generate the two translation files specified in the .pro configuration file, namely pptslidegenerator.fr.ts and pptslidegenerator.en.ts.
Local Language Code
The language used in the translation file’s name must follow strict rules. It is composed of the first letters group of the language string compliant with RFC 1766. In the following table, you will find an extract of the commonly supported language strings provided by Microsoft (Microsoft Language Strings):
|en-us||English (United Kingdom)|
|en-gb||English (United States)|
Thanks to the Python locale module and its getdefaultlocale function, it’s possible to retrieve the computer system’s local language. This allows us to load the right language file at the application startup automatically. The getdefaultlocale function tries to determine the default locale settings. If the call is successful, it returns them as a tuple of the form (language code, encoding). The language code is composed of two parts, the language, and the country:
As we are interested only by the language, the developer has to use the following code:
Translation with Qt Linguist
Qt Linguist is a handy tool used to makes text translation very easy.
The translator has first to open a .ts translation file (step 5). It’s also possible to open all the translation files simultaneously to translate the texts in different languages in parallel. The translator can now proceed to the translation of the different texts:
Let’s have a quick look at the different sections of this window:
- Context: The Context view lists the contexts in which the strings to be translated appear. In this example, @default corresponds to the pptslidegenerator.py project file as MainWindow corresponds to the mainwin.py file (MainWindow is the object name set in Qt Designer for the main window). The number of translated strings is mentioned on the right side.
- Strings: The Strings view lists the strings found in a context. These strings were extracted thanks to the presence of the tr() or translate() function into the source code. The following table indicates the current translation state for each string:
|The translator has accepted the translation, and the translation passed all the validation tests. If the translation field is empty, the translator has decided to leave it blank.|
|The translator has accepted the translation, but the translation didn’t pass all the validation tests. The validation test failures are displayed in the Warnings view.|
|Not Accepted||The string has a translation that passed all the validation tests, but the translator didn’t accept the translation yet.|
|No Translation||There is no translation for the string.|
|Validation Failures||The string has a translation, but the translation didn’t pass all the validation tests. Validation test failures are displayed in the Warnings view.|
|Obsolete||The string is obsolete because it is no longer used in the context.|
- Translation area (middle right): Area dedicated to translating the current string in the Translation field. Based on the translation file’s name, Qt Linguist automatically detects the language used for the translation.
If the string can be translated in the plural, Qt Linguist will ask for two translations: one in the singular (“There is %n file“) and one in the plural (“There are %n files“).
- Warnings: The Warnings view lists all texts that fail validation tests.
Once the translator has completed the translation and validation of all the texts, he must save the translation file(s).
Compilation of Translation Files
The translator must compile the translation file(s) into a .qm binary format (step 6). The easiest way for the translator consists of using the Qt Linguist integrated release function (“Release” if only one file is open or “Release All” for multiple files):
To keep your application’s coherence, I strongly recommend storing your binary translation files with other resources (logo, pictures, etc.) into a specific resources folder:
Loading of Translation File(s) into Python Application
The last step of the process consists of loading the translation files into the application. When the developer decides to distribute the application, two options are available for the resources files:
- Distribute the application with the resources files folder, which will be separate from the application’s executable.
- Compile the resources files into a Python file, which will be part of the application’s executable (step 7, recommended solution).
For option B, the developer must first update the resources file Resources.qrc generated by Qt Designer by adding the translation binary files:
The section related to the language is defined inside the qresource tag.
Then, the developer has to use the pyrcc5 Qt tool to generate the Python resources file which will contain all the compiled resources (logo and translation files in our example):
You will find hereunder the code to implement with the specificities related to each option (A or B):
- Modules import
- Translator class initialization
A / B:
We recognize in this code the language determined with the getdefaultlocale function. Furthermore, we have to add a specific resource_path function to get the path of the resources folder. This is particularly important when the developer decides to bundle the application and all its dependencies into a single executable. It’s indeed due to the fact that, when started, the executable creates a temporary folder named _MEIxxxxxx (xxxxxx is a random number) in the appropriate temporary folder location for this Operating System.
- Language Change
Thanks to the following code, it’s possible to change the language at run-time:
As you may have noticed, translating Qt applications is a very well thought process and everything is planned.
You now have all the tools in hand to broadcast your program anywhere in the world, you just need to find the good translator!