qt - 为什么我的 Qt5 语言翻译未加载?

标签 qt cmake internationalization qml qt5

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

├── 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 我得到一个显示“Hello”的按钮,而不是显示“Bonjour”的按钮。我花了几个小时试图解决这个问题,这也让我想到了第二个问题:通常如何解决 Qt 语言翻译问题?这是我第一次,我找不到任何相关文档。

最佳答案

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

除非您想支持动态语言切换,否则不需要使用QTranslator。启动时,QML 运行时会自动从 i18n 子目录加载翻译文件 qml_.qm(qml_xx_XX.qm,其中 xx 是 ISO639,XX 是可选的 ISO 3166 代码)根 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;

关于qt - 为什么我的 Qt5 语言翻译未加载?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71672073/

相关文章:

c++ - 当我按 alt-tab 键进入其中任何一个窗口时,如何将所有窗口强制置于最前面?

c++ - QT 重绘/重绘/更新/做某事

c++ - 无法使用 CMake 和 CUDA 构建共享库

c++ - 检查是否从 CMake 生成 Visual Studio 解决方案或 Makefile

c++ - 带 nfs 挂载的 QFileSystemWatcher

c++ - 使用带有仅 header 的 CMake 项目的 clang-tidy

按下瑞典键 å、ä 和 ö 时,jQuery event.keyCode 0

reactjs - Next.js 域路由与子域

java - 在 Tomcat 上处理 URI 中的字符编码

python - QWebEngineView 使用 setHtml(...) 加载 SVG 失败