为什么我的 Qt5 语言翻译没有加载?

Why aren't my Qt5 language translations loading?

我正在尝试使用 CMake 编写一个带有语言翻译的简单 qml 应用程序,尽管该应用程序可以运行,但它从不显示翻译。我在 Linux 平台上,CMake 版本 3.22.2 和 Qt 版本 3.15.2 这是目录结构:

├── CMakeLists.txt
└── src
    ├── CMakeLists.txt
    ├── main.cpp
    ├── silly.qrc
    └── qml
        ├── silly.qml
        └── translations
            ├── qml_de.ts
            ├── qml_en.ts
            └── qml_fr.ts

CMakeLists.txt

cmake_minimum_required(VERSION 3.22)
project(silly VERSION 1.0.0)
add_subdirectory(src)

src/CMakeLists.txt

cmake_minimum_required(VERSION 3.22)
find_package(Qt5 COMPONENTS Qml Quick LinguistTools REQUIRED)
set(TRANSLATIONS 
    qml/translations/qml_en.ts
    qml/translations/qml_fr.ts
    qml/translations/qml_de.ts
)
qt5_create_translation(QM_FILES ${CMAKE_CURRENT_SOURCE_DIR} ${TRANSLATIONS})
qt5_add_resources(QRC_RESOURCES "silly.qrc") 

add_executable(silly main.cpp 
    "${QRC_RESOURCES}"
    "${QM_FILES}"
)
target_compile_features(silly PUBLIC cxx_std_17)
set_target_properties(silly PROPERTIES AUTOMOC ON AUTORCC ON)
target_link_libraries(silly PRIVATE Qt5::Quick Qt5::Qml)
target_include_directories(silly
    PUBLIC
        $<INSTALL_INTERFACE:.>
        $<BUILD_INTERFACE:${CMAKE_BINARY_DIR}>
)
install(TARGETS silly)

src/main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);
    QQmlApplicationEngine engine;
    engine.addImportPath("qrc:/");
    engine.load(QUrl("qrc:/qml/silly.qml"));

    return app.exec();
}

src/silly.qrc

<!DOCTYPE RCC><RCC version="1.0">
    <qresource prefix="/qml">
        <file alias="silly.qml">qml/silly.qml</file>
    </qresource>
</RCC>

src/qml/silly.qml

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15

ApplicationWindow {
    visible: true

    Button {
        anchors.fill: parent
        spacing: 20
        text: qsTr("Hello")
    }
}

src/qml/translations/qml_de.ts

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="de_DE">
<context>
    <name>silly</name>
    <message>
        <location filename="../silly.qml" line="11"/>
        <source>Hello</source>
        <translation>Hallo</translation>
    </message>
</context>
</TS>

src/qml/translations/qml_en.ts

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="en_US">
<context>
    <name>silly</name>
    <message>
        <location filename="../silly.qml" line="11"/>
        <source>Hello</source>
        <translation type="unfinished"></translation>
    </message>
</context>
</TS>

src/qml/translations/qml_fr.ts

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="fr_FR">
<context>
    <name>silly</name>
    <message>
        <location filename="../silly.qml" line="11"/>
        <source>Hello</source>
        <translation>Bonjour</translation>
    </message>
</context>
</TS>

它构建并运行时没有错误,但是当我尝试用它进行测试时: LANGUAGE=fr src/silly 我得到一个显示“你好”的按钮,而不是显示“Bonjour”的按钮。几个小时以来,我一直在努力解决这个问题,这也让我想到了第二个问题:通常如何解决 Qt 语言翻译问题?这是我的第一次,我找不到相关的文档。

这是非常糟糕的文档记录,它与使用专用 qmake 配置参数 embed_translations 的 ready-made 示例一起神奇地工作。我建议您查看原始示例的构建目录,其中生成了 .qm 文件和一个特殊的 qrc 文件 qmake_qmake_qm_files.qrc

除非你想支持动态语言切换,否则你不需要使用QTranslator。在启动时,QML 运行时自动从i18n 根 QML 文件的子目录,基于系统语言,如果找到的话。

您需要将 .qm 文件放入 qrc:/qml/i18n/ 文件夹,因为您的主要 qml 文件位于 qrc:/qml/.

使用 CMake 你可以按如下方式进行:

添加一个新的 qrc 文件,例如cmake_qm_files.qrc 到您的项目

<RCC>
    <qresource prefix="/qml/i18n">
        <file>qml_de.qm</file>
        <file>qml_en.qm</file>
        <file>qml_fr.qm</file>
    </qresource>
</RCC>

让 CMake 将 qrc 文件复制到创建 .qm 文件的二进制目录

configure_file(cmake_qm_files.qrc ${CMAKE_BINARY_DIR} COPYONLY)

将 qrc 文件资源编译并嵌入到您的可执行文件中

add_executable(silly main.cpp
    ${QRC_RESOURCES}
    ${CMAKE_BINARY_DIR}/cmake_qm_files.qrc
)

我通常使用 QLocale 进行翻译测试,如下所示:

QGuiApplication app(argc, argv);

QLocale systemLocale = QLocale::system();
QLocale::Language language = systemLocale.language();
QLocale::Country country = systemLocale.country();
qDebug() << "System locale language:" << language << ", country:" << country;

// TEST: change default locale by removing comments below
// language = QLocale::French;
// country = QLocale::France;
language = QLocale::English;
country = QLocale::Australia;
QLocale locale(language, country);
qDebug() << "Changing default locale to language:" << locale.language() << ", country:" << locale.country();
QLocale::setDefault(locale); // TEST: set default locale to something else than system locale

QQmlApplicationEngine engine;