CMake:How To Build Qt4 Software: Difference between revisions

From KitwarePublic
Jump to navigationJump to search
(Initial draft)
 
(More info about Qt's tr())
Line 9: Line 9:
#* QString log_message("Reading Model"); would not be translated
#* QString log_message("Reading Model"); would not be translated
#* QString log_message(tr("Reading Model")); would be translated
#* QString log_message(tr("Reading Model")); would be translated
#* eg: labelFilename->setText( QString(tr("Type filename here:")) )
#* eg: labelFilename->setText( tr("Type filename here:") )
#* Note that tr() is effectively QString()
#* Note also that if you call tr() from outside a QObject-derived class, you'll instead have to do something like QCoreApplication::translate("context","Reading Model") where "context" will appear in the linguist program to help you figure out the string's context when you type in the translated versions.
# Translation XML files (*.ts), which lists the strings and the translations for those strings.  You need to create one for each language you want a translation for. Put them all together translations/ folder.
# Translation XML files (*.ts), which lists the strings and the translations for those strings.  You need to create one for each language you want a translation for. Put them all together translations/ folder.
#* mkdir translations
#* mkdir translations

Revision as of 05:55, 31 October 2008

Translations

Note: These are notes on how I support translations in my application. There is more than one way to do it, and my way may be wrong. Please correct mistakes found in this page.

Qt4 supports I18N (Internationalisation) and can assist the programmer to translate all of the appropriately tagged strings in an application to any number of languages.

The system is made up of:

  1. The application source files (*.h *.hpp *.hxx *.cpp *.cxx etc). Within the source files, the programmer tags static strings for translation, with tr():
    • QString log_message("Reading Model"); would not be translated
    • QString log_message(tr("Reading Model")); would be translated
    • eg: labelFilename->setText( tr("Type filename here:") )
    • Note that tr() is effectively QString()
    • Note also that if you call tr() from outside a QObject-derived class, you'll instead have to do something like QCoreApplication::translate("context","Reading Model") where "context" will appear in the linguist program to help you figure out the string's context when you type in the translated versions.
  2. Translation XML files (*.ts), which lists the strings and the translations for those strings. You need to create one for each language you want a translation for. Put them all together translations/ folder.
    • mkdir translations
    • touch translations/myapp_fr.ts (for French)
    • touch translations/myapp_ja.ts (for Japanese)
  3. A program "lupdate" for updating the strings in the Translation *.ts files. CMake can coordinate this task.
  4. A GUI program "linguist" which assists you to specify translations for all the strings found in the application source code. The translations are stored in the *.ts files.
  5. Translation BINARY files (*.qm), which is an efficient format used during execution. The program "lrelease" converts .ts files to .qm files. CMake can coordinate this too.
  6. And lastly, in your application you can control which translations to load.


Configuring CMake to Help Translate

Configuration

Do the above, especially the bit where you put all the .ts files into a translations folder (blank .ts files are good to start with).


In your root CMakeLists.txt, put the following near the top, before any add_subdirectory() calls that you want translated:

set (FILES_TO_TRANSLATE )

In each subdirectory/CMakeLists.txt, I assumes that you have set 3 specific variables, eg by doing this:

file (GLOB HEADER_FILES *.h *.hpp)
file (GLOB CPP_FILES *.cpp)
file (GLOB UI_FILES *.ui)

And then you can add this:

set (FILES_TO_TRANSLATE ${FILES_TO_TRANSLATE} ${CPP_FILES} ${UI_FILES} ${HEADER_FILES} PARENT_SCOPE)

Note that if you do something like set (HEADER_FILES a_header.h) It will NOT work as will be processing the headers in the project root dir, and a_header.h does not have the full path. Instead, if you must specify without glob, do this:

set (HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/a_header.h)

Now back to the project root CMakeLists.txt file, at the bottom add:

file (GLOB TRANSLATIONS_FILES translations/*.ts)

option (UPDATE_TRANSLATIONS "Update source translation translations/*.ts
files (WARNING: make clean will delete the source .ts files! Danger!)")
if (UPDATE_TRANSLATIONS)
  qt4_create_translation(QM_FILES ${FILES_TO_TRANSLATE}
${TRANSLATIONS_FILES})
else (UPDATE_TRANSLATIONS)
  qt4_add_translation(QM_FILES ${TRANSLATIONS_FILES})
endif (UPDATE_TRANSLATIONS) 

add_custom_target (translations_target DEPENDS ${QM_FILES})

install(FILES ${QM_FILES} DESTINATION
${CMAKE_INSTALL_PREFIX}/translations)


Usage - Normal

You just want to generate the .qm files, so configure cmake with the UPDATE_TRANSLATIONS flag turned off. CMake will not modify your .ts files, and the new .qm files will be built and stored in the project binary folders. When you run "make install" (or equivalent), it'll copy the .qm files into a translations folder in the Install folder.
Note that you can continue to update the translations via the linguist step (see above). But any new strings in your source code will not appear in your .ts files.

Usage - Updating the .ts files

When you want it to process all your source files (looking for new texts to translate), configure cmake to turn on UPDATE_TRANSLATIONS, and then make your project. CMake will modify your .ts files in your SOURCE folders in addition to generating the .qm files.
WARNING: Be aware that CMake will be updating the source .ts files, which means that if you do a make clean, it will DELETE your source .ts files!!! So it would be a good idea to switch off UPDATE_TRANSLATIONS as soon as possible.