See also: Merge Qt .ts files
In the internationalized world of software development, it is common to encounter scenarios where you need to support multiple languages in your application. In this blog post, we will walk you through a simple yet effective way of changing the default language of a Qt project from Finnish to English, using a Python script.
Note: This is an experiment in AI-assisted blog writing. Contains AI-assisted, untested instructions.
Let’s dive in!
The Qt Translation Process
Qt provides the tr()
function for marking text to be translated. These translations are stored in .ts
files, which are XML files containing the original text and the translated text. Typically, the original text is written in the source code, and the translated text is added later using Qt’s Linguist tool.
Changing the Source Language
Suppose you have a project where the source language in the tr()
calls is Finnish, and you have an English translation file. You want to change the source language from Finnish to English, and then generate a Finnish translation file.
First, you need to install the lxml library, which we will use to parse the .ts files:
pip install lxml
Then, create a Python script named change_language.py
with the following content:
import os
import re
from lxml import etree
# The rest of the Python script goes here...
The script includes three main functions: replace_tr_calls()
, generate_finnish_ts_file()
, and main()
.
replace_tr_calls()
This function walks through the Qt project’s source files, replacing Finnish strings in tr()
calls with English translations:
def replace_tr_calls(src_folder, translations):
for root, _, files in os.walk(src_folder):
for file in files:
if file.endswith('.cpp') or file.endswith('.h'):
filepath = os.path.join(root, file)
with open(filepath, 'r', encoding='utf-8') as f:
content = f.read()
updated_content = content
for finnish, english in translations.items():
updated_content = re.sub(
f'tr\("{re.escape(finnish)}"\)',
f'tr("{english}")',
updated_content
)
if content != updated_content:
with open(filepath, 'w', encoding='utf-8') as f:
f.write(updated_content)
generate_finnish_ts_file()
This function generates a new Finnish .ts file for translation:
def generate_finnish_ts_file(output_file, translations):
root = etree.Element('TS', version="2.1", language="fi")
context = etree.SubElement(root, 'context')
name = etree.SubElement(context, 'name')
name.text = 'MyApp'
for finnish, english in translations.items():
message = etree.SubElement(context, 'message')
source = etree.SubElement(message, 'source')
source.text = english
translation = etree.SubElement(message, 'translation')
translation.text = finnish
with open(output_file, 'wb') as f:
f.write(etree.tostring(root, pretty_print=True, encoding='utf-8'))
main()
def main():
english_ts_file = 'path/to/english.ts'
src_folder = 'path/to/your/src'
output_finnish_ts_file = 'path/to/new_finnish.ts'
tree = etree.parse(english_ts_file)
translations = {}
for message in tree.xpath('//message'):
source = message.find('source').text
translation = message.find('translation').text
if source and translation:
translations[translation] = source
replace_tr_calls(src_folder, translations)
generate_finnish_ts_file(output_finnish_ts_file, translations)
if name == 'main':
main()
The main()
function ties everything together. It reads the English .ts file, extracts the translations, replaces the Finnish strings in the source files, and generates the new Finnish .ts file:
You can replace the paths in the `main()` function with the appropriate file paths for your Qt project. Finally, you can run the script using:
python change_language.py
Handling Multiple Translation Files
You can upgrade this script to handle multiple translation files with Finnish as their source language. Modify the main()
function to take a list of translation files and loop through them to replace the source language strings.
Let’s add a new function named process_translation_file()
to process each translation file:
def process_translation_file(translation_file, src_folder, output_folder):
tree = etree.parse(translation_file)
translations = {}
target_language = tree.getroot().get('language')
for message in tree.xpath('//message'):
source = message.find('source').text
translation = message.find('translation').text
if source and translation:
translations[translation] = source
replace_tr_calls(src_folder, translations)
output_file = os.path.join(output_folder, f'new_{target_language}.ts')
generate_translated_ts_file(output_file, translations, target_language)
Now, modify the main()
function to loop through multiple translation files:
def main():
translation_files = [
'path/to/finnish.ts',
'path/to/another_translation.ts',
# add more translation files as needed
]
src_folder = 'path/to/your/src'
output_folder = 'path/to/output'
for translation_file in translation_files:
process_translation_file(translation_file, src_folder, output_folder)
if __name__ == '__main__':
main()
With this modification, the script can handle multiple translation files and replace the Finnish strings with English translations in the source code, while generating new translation files for each target language with English as the source language.
Conclusion
In this post, we’ve shown you how to use Python and the lxml library to change the default language of a Qt project from Finnish to English, and to generate a new Finnish translation file. We also discussed how to extend this script to handle multiple translation files.
We hope this guide is helpful in your internationalization efforts. Happy coding!