Search code examples
c++qtcmakelocalizationresources

Translation resources are not manually added to the executable file


I've created a small test project to demonstrate my issue.

The essence of the problem is that, according to the official documentation for qt_add_translations, the two code examples I've provided below should be roughly equivalent. Moreover, according to the functions qt_add_lupdate, qt_add_lrelease, and qt_add_resources, translation files should be added to the executable file.

However, for some reason, when using the second variant, translation files are not added to the executable file.

cmake_minimum_required(VERSION 3.27)
set(CMAKE_CXX_STANDARD 23)

project(TestQtWidgetsProject)

set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)

# Executable
add_executable(${PROJECT_NAME} main.cpp)

# Library
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
target_link_libraries(${PROJECT_NAME} Qt::Core Qt::Gui Qt::Widgets)

# Translations
find_package(Qt6 REQUIRED LinguistTools)

# =======================================

# Variant 1

#qt_add_translations(TestQtWidgetsProject
#        INCLUDE_DIRECTORIES
#            ${PROJECT_SOURCE_DIR}
#        TS_FILES
#            translation_ru.ts)

# Variant 2

qt_add_lupdate(${PROJECT_NAME} INCLUDE_DIRECTORIES ${PROJECT_SOURCE_DIR} TS_FILES translation_ru.ts)
qt_add_lrelease(${PROJECT_NAME} TS_FILES translation_ru.ts QM_FILES_OUTPUT_VARIABLE QM_FILES)
qt_add_resources(${PROJECT_NAME} "translations" PREFIX "/i18n" FILES ${QM_FILES})

# =======================================

# Dependencies
add_dependencies(${PROJECT_NAME} ${PROJECT_NAME}_lupdate)
add_dependencies(${PROJECT_NAME} ${PROJECT_NAME}_lrelease)

main.cpp

#include <QApplication>
#include <QPushButton>
#include <QTranslator>

int main(int argc, char* argv[]) {
    QApplication a(argc, argv);
    QTranslator translator;

    qDebug() << translator.load(":/i18n/translation_ru");
    qDebug() << QApplication::installTranslator(&translator);

    QPushButton button(QApplication::tr("Hello, World!") + QApplication::tr(" qwe"), nullptr);
    button.resize(200, 100);
    button.show();
    return QApplication::exec();
}

Output when using the first variant:

true
true

Output when using the second variant:

false
false

Solution

  • In the qt_add_resources function call, it is needed to add the BASE parameter equal to the path of the folder from which resource file aliases are resolved.

    For example, if you set BASE as ${CMAKE_CURRENT_BINARY_DIR}, then

    translator.load(":/i18n/translation_ru")
    

    will return true,
    whereas if you set BASE as ${PROJECT_SOURCE_DIR}, to load the translation file, you'll need to write:

    translator.load(":/i18n/cmake-build-debug/translation_ru");
    

    (this example is provided for better understanding)

    Thus the correct code for the second variant would be:

    qt_add_lupdate(${PROJECT_NAME} INCLUDE_DIRECTORIES ${PROJECT_SOURCE_DIR} TS_FILES translation_ru.ts)
    qt_add_lrelease(${PROJECT_NAME} TS_FILES translation_ru.ts QM_FILES_OUTPUT_VARIABLE QM_FILES)
    qt_add_resources(${PROJECT_NAME} "translations" PREFIX "/i18n" BASE ${CMAKE_CURRENT_BINARY_DIR} FILES ${QM_FILES})