是否有可能为Qt中的每种语言编译单独的应用程序?

时间:2012-06-11 05:27:08

标签: c++ qt localization projects-and-solutions

所以我创建了N种语言的翻译(使用Qt语言学家)。我想将我的应用编译成N个应用,这些应用的前缀不同,例如_en_US_fr_FR嵌入到每个翻译的字符串中。此外,我想保留一个版本的应用程序,它将自动确定当前具有所有翻译版本的平台语言。如何更改.pro文件以获得此类结果?

1 个答案:

答案 0 :(得分:1)

我认为嵌入所有翻译并在运行时决定要容易得多 加载哪一个。也许您可以提供命令行开关或选项 覆盖系统区域设置。你甚至不必将它们嵌入可执行文件中, 您可以将它们运送到"翻译"目录。在运行时获取系统区域设置 你可以使用QLocale class:

Application application(argc, argv);

QString locale = QLocale::system().name();
QString translationsDir = ":/translations";

QTranslator appTranslator;
QTranslator qtTranslator;

appTranslator.load(locale, translationsDir);
qtTranslator .load("qt_" + locale,
                    QLibraryInfo::location(QLibraryInfo::TranslationsPath));

application.installTranslator(& appTranslator);
application.installTranslator(& qtTranslator);

无论如何,如果你真的想以你的方式做,你可以依靠环境变量LANGUAGE_ID来检测什么语言 嵌入您的构建中,然后为每个可用项目重建项目 语言。这可能需要很长时间,但也许你只能为此而努力 最终建设。

以下是一个例子:

#include <iostream>

int main(int argc, char *argv[])
{
#ifdef EMBED_ONLY_ONE_LANGUAGE
    std::cout << "Embedded language is " << LANGUAGE_ID << std::endl;
#elif EMBED_ALL_LANGUAGES
    std::cout << "Embedded all languages" << std::endl;
#else
    std::cout << "What???" << std::endl;
#endif
}

这是.pro文件:

TEMPLATE = app
DEPENDPATH += .
INCLUDEPATH += .
TARGET = SomeName

CONFIG -= qt
CONFIG += console

# Input
SOURCES += main.cpp

# It seems that "equals" does not work with environment variables so we
# first read it in a local variable.
LANGUAGE_ID=$$(LANGUAGE_ID)

equals(LANGUAGE_ID,) {
    # No language id specified. Add the build instructions to embed all the
    # translations and to decide at runtime which one to load.
    message(No language id specified)

    # This adds a preprocessor variable so that the program knows that it has
    # every language.
    DEFINES *= EMBED_ALL_LANGUAGES
} else {
    # A language id was specified. Add the build instructions to embed only
    # the relative translation.
    message(Specified language id: $$LANGUAGE_ID)

    # This adds a preprocessor variable LANGUAGE_ID whose value is the language.
    DEFINES *= LANGUAGE_ID=\\\"$$LANGUAGE_ID\\\"

    # This adds a preprocessor variable so that the program knows that it has
    # only one language.
    DEFINES *= EMBED_ONLY_ONE_LANGUAGE

    # This renames the executable.
    TARGET=$${TARGET}_$$(LANGUAGE_ID)
}

它使用了未记录的test function equals。请注意,如果你 更改环境变量LANGUAGE_ID的值,你必须运行qmake 再次(可能在删除了Makefile之后)。

一个(或许更好)替代方案是使用CMake并将语言ID指定为 一个CMake的命令行变量:

cmake_minimum_required(VERSION 2.6)
project(SomeName)

set(SOURCES main.cpp)

add_executable(SomeName ${SOURCES})

if(${LANGUAGE_ID} MATCHES "[a-z][a-z]_[A-Z][A-Z]")
    # A language id was specified. Add the build instructions to embed only
    # the relative translation.
    message("Embedding language ${LANGUAGE_ID}")

    # This adds a preprocessor variable LANGUAGE_ID whose value is the language.
    add_definitions("-DLANGUAGE_ID=\"${LANGUAGE_ID}\"")

    # This adds a preprocessor variable so that the program knows that it has
    # only one language.
    add_definitions("-DEMBED_ONLY_ONE_LANGUAGE")

    # This renames the executable.
    set_target_properties(SomeName PROPERTIES OUTPUT_NAME "SomeName_${LANGUAGE_ID}")

else(${LANGUAGE_ID} MATCHES "[a-z][a-z]_[A-Z][A-Z]")
    # No language id specified. Add the build instructions to embed all the
    # translations and to decide at runtime which one to load.
    message("Not embedding any language")

    # This adds a preprocessor variable so that the program knows that it has
    # every language.
    add_definitions("-DEMBED_ALL_LANGUAGES")

endif(${LANGUAGE_ID} MATCHES "[a-z][a-z]_[A-Z][A-Z]")