Localization 如何使用cmake和QRC将Qt4 qm文件集成到二进制文件中?

Localization 如何使用cmake和QRC将Qt4 qm文件集成到二进制文件中?,localization,qt4,internationalization,translation,cmake,Localization,Qt4,Internationalization,Translation,Cmake,我有一个Qt4 CMake项目,我想将i18n的QM文件集成到输出二进制文件中。以下是我到目前为止生成TS和QM文件的规则: set(myapp_TRANSLATIONS i18n/myapp_de.ts ) set(FILES_TO_TRANSLATE ${myapp_SRCS} ${myapp_MOC_HDRS} ) QT4_CREATE_TRANSLATION(QM_FILES ${FILES_TO_TRANSLATE} ${myapp_TRANSLATIONS

我有一个Qt4 CMake项目,我想将i18n的QM文件集成到输出二进制文件中。以下是我到目前为止生成TS和QM文件的规则:

set(myapp_TRANSLATIONS
    i18n/myapp_de.ts
)

set(FILES_TO_TRANSLATE
    ${myapp_SRCS}
    ${myapp_MOC_HDRS}
)

QT4_CREATE_TRANSLATION(QM_FILES ${FILES_TO_TRANSLATE} ${myapp_TRANSLATIONS})
QT4_ADD_TRANSLATION(QM ${myapp_TRANSLATIONS})
我尝试了以下操作以将QM文件添加到可执行文件:

add_executable(myapp ${myapp_SRCS} ${myapp_MOC_SRCS} ${myapp_RCC_SRCS} ${QM})
这是main.cpp中的初始化:

QTranslator qtTranslator;
qtTranslator.load("qt_" + QLocale::system().name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath));
app.installTranslator(&qtTranslator);

QTranslator appTranslator;
appTranslator.load("myapp_" + QLocale::system().name());
app.installTranslator(&appTranslator);
但是,
strings mypp
显示翻译没有进入二进制

更新:我将每个qm文件添加到
i18n/translations.qrc

<!DOCTYPE RCC><RCC version="1.0">
  <qresource prefix="/resources">
    <file>myapp_de.qm</file>
    <file>  ...   .qm</file>
  </qresource>
</RCC>
并向可执行依赖项添加
myapp\u QM\u RCC\u SRCS


但是,由于CMake进行了影子构建(在源目录之外构建),但解析了QRC文件,以寻找与QRC文件相关的引用文件的依赖项,因此在构建期间这一点会失败(很好的功能,但没有制定如何在该位置构建QM文件的规则)。QM文件在
${CMAKE\u CURRENT\u BINARY\u DIR}
中(它们属于使用阴影构建的位置),但在
${CMAKE\u CURRENT\u SOURCE\u DIR}
中需要它(未生成的文件应该在这里-因此两个位置都是正确的,取决于情况).

您需要使用Qt资源系统将翻译直接包含到应用程序二进制文件中。使用QT4_ADD_RESOURCES宏执行此操作。这里有一些如何使用它的例子:

我遇到了完全相同的问题。我提出了以下解决方案:

创建一个仅包含预期QM文件的QRC文件,并为其指定不同的前缀,以使其不会与其他资源冲突:

<RCC>
    <qresource prefix="/translators">
    <file>myapp_en.qm</file>
    </qresource>
</RCC>

如果您使用Qt5,请使用
${Qt5Core\u RCC\u EXECUTABLE}
而不是
${QT\u RCC\u EXECUTABLE}

我的解决方案是从头开始生成带有编译翻译的
ts.qrc
XML文件,然后将其与应用程序进行编译

下面是一个例子:

file(GLOB QRC_FILES *.qrc)
file(GLOB TS_FILES ts/*.ts)
...

# Option for updating translations
option(UPDATE_TRANSLATIONS "Update source translation ts/*.ts files (WARNING: make clean will delete the source *.ts files. Danger!)" OFF)
if(UPDATE_TRANSLATIONS)
qt4_create_translation(QM_FILES ${TS_FILES})
endif()
...
# Compiling translations *.ts -> *.qm
qt4_add_translation(QM_FILES ${TS_FILES})
...
# Create translations QRC file - ts.qrc
set(TRANSLATIONS_QRC "${CMAKE_CURRENT_BINARY_DIR}/ts.qrc")
file(WRITE ${TRANSLATIONS_QRC} "<RCC>\n\t<qresource prefix=\"/ts\">")
foreach(QM_FILE ${QM_FILES})
    get_filename_component(QM_FILE_NAME ${QM_FILE} NAME)
    file(APPEND ${TRANSLATIONS_QRC} "\n\t\t<file alias=\"${QM_FILE_NAME}\">${QM_FILE_NAME}</file>")
endforeach()
file(APPEND ${TRANSLATIONS_QRC} "\n\t</qresource>\n</RCC>")
list(APPEND QRC_FILES ${TRANSLATIONS_QRC})
...
# Compiling *.qrc files
qt4_add_resources(QRC_SRCS ${QRC_FILES})
...
# Add compiled resources to executable dependency list
add_executable(${APP_NAME} ... ${QRC_SRCS})

ts
dir中的文件最初由
lupdate
工具生成。

我在CMake 3.0(可能更早)中找到了一种非常简单的方法,无需
ADD\u CUSTOM\u命令
和其他复杂操作

首先,您应该创建一个QRC文件,其中列出了所有
.qm
文件(谢谢,):

然后将
${myapp\u QM\u RC}
与其他源一起包含在
添加可执行文件中。

注意:对于Qt4,将所有
qt5
前缀替换为
Qt4

是的,我已经知道了。但它不起作用:CMake 2.6发现了QRC的源代码(在我的例子中是要生成的QM文件),但无法知道如何构建此文件,因为它希望它位于源路径,而不是构建路径(它以前创建的地方)。看起来很有希望,我将尝试一下+1我已经一步一步地建立了你的想法,以了解你是如何做到的。很好,很好!像charmDon一样工作不要停止阅读,有一个更简单的方法可以做到:很好,但是它不能与并行生成(make-jSOMETHING)一起工作,而不是
${CMAKE_BINARY_DIR}
(根构建目录),它应该是
${CMAKE_CURRENT_BINARY_DIR}
(构建目录中的子目录),因为那是复制到.awesome的地方,这甚至消除了禁用CLEAN_NO_自定义属性的需要!
# Change 'myapp_en' to be the base file name of the qrc file.
SET( trans_file myapp_en )
SET( trans_srcfile ${CMAKE_CURRENT_SOURCE_DIR}/${trans_file}.qrc)
SET( trans_infile ${CMAKE_CURRENT_BINARY_DIR}/${trans_file}.qrc)
SET( trans_outfile ${CMAKE_CURRENT_BINARY_DIR}/qrc_${trans_file}.cxx)

# Copy the QRC file to the output directory, because the files listed in the 
# qrc file are relative to that directory.
ADD_CUSTOM_COMMAND(
    OUTPUT ${trans_infile}
    COMMAND ${CMAKE_COMMAND} -E copy ${trans_srcfile} ${trans_infile}
    MAIN_DEPENDENCY ${trans_srcfile}
    )

# Run the resource compiler (rcc_options should already be set). We can't
# use QT4_ADD_RESOURCES because the qrc file may not exist yet.
ADD_CUSTOM_COMMAND(
    OUTPUT ${trans_outfile}
    COMMAND ${QT_RCC_EXECUTABLE}
    ARGS ${rcc_options} -name ${trans_file} -o ${trans_outfile} ${trans_infile}
    MAIN_DEPENDENCY ${trans_infile}
    DEPENDS ${qm_files}
    )

# Add compiled resources to executable dependency list
ADD_EXECUTABLE( ${APP_NAME} ... ${trans_outfile} )
file(GLOB QRC_FILES *.qrc)
file(GLOB TS_FILES ts/*.ts)
...

# Option for updating translations
option(UPDATE_TRANSLATIONS "Update source translation ts/*.ts files (WARNING: make clean will delete the source *.ts files. Danger!)" OFF)
if(UPDATE_TRANSLATIONS)
qt4_create_translation(QM_FILES ${TS_FILES})
endif()
...
# Compiling translations *.ts -> *.qm
qt4_add_translation(QM_FILES ${TS_FILES})
...
# Create translations QRC file - ts.qrc
set(TRANSLATIONS_QRC "${CMAKE_CURRENT_BINARY_DIR}/ts.qrc")
file(WRITE ${TRANSLATIONS_QRC} "<RCC>\n\t<qresource prefix=\"/ts\">")
foreach(QM_FILE ${QM_FILES})
    get_filename_component(QM_FILE_NAME ${QM_FILE} NAME)
    file(APPEND ${TRANSLATIONS_QRC} "\n\t\t<file alias=\"${QM_FILE_NAME}\">${QM_FILE_NAME}</file>")
endforeach()
file(APPEND ${TRANSLATIONS_QRC} "\n\t</qresource>\n</RCC>")
list(APPEND QRC_FILES ${TRANSLATIONS_QRC})
...
# Compiling *.qrc files
qt4_add_resources(QRC_SRCS ${QRC_FILES})
...
# Add compiled resources to executable dependency list
add_executable(${APP_NAME} ... ${QRC_SRCS})
/ - source code root
/rc.qrc - contains app icons etc.
/ts/appname_*.ts - application translations
...
/build - build root
/build/appname_*.qm - compiled translations
/build/ts.qrc - translations rescources
/build/Release/qrc_rc.cxx - compiled icon etc. resources
/build/Release/qrc_ts.cxx - compiled translation resources
<RCC>
  <qresource prefix="/translators">
    <file>myapp_en.qm</file>
  </qresource>
</RCC>
# Change lang.qrc to the name of QRC file, created on the previous step
set(lang_qrc "lang.qrc")
configure_file(${lang_qrc} ${lang_qrc} COPYONLY)
qt5_add_translation(myapp_QM ${myapp_TRANSLATIONS})
qt5_add_resources(myapp_QM_RC ${CMAKE_CURRENT_BINARY_DIR}/${lang_qrc})