QT/QML国际化:中英文界面切换显示(cmake方式使用)

目录

前言

实现步骤

[1. 准备翻译文件](#1. 准备翻译文件)

[2. 翻译字符串](#2. 翻译字符串)

3.设置应用程序语言

[cmake 构建方式](#cmake 构建方式)

示例代码

总结

[1. 使用 file(GLOB ...)](#1. 使用 file(GLOB ...))

[2. 引入其他资源文件](#2. 引入其他资源文件)

再次生成翻译文件

[5. 手动更新和生成.qm文件](#5. 手动更新和生成.qm文件)

其他资源


前言

在当今全球化的软件开发环境中,应用程序的国际化(i18n)与本地化(l10n)能力已成为衡量其专业度和用户体验的重要标准之一。QT/QML作为一套强大的跨平台应用程序开发框架,其内置的国际化支持机制使得开发者能够轻松地为应用添加多语言功能,从而满足不同地域用户的语言需求。本文将深入探讨如何在QT/QML项目中实现中英文显示的国际化,从基础概念到具体实施步骤,帮助开发者构建出更加友好、包容的应用界面。

QT框架提供了完整的国际化支持,包括字符串提取、翻译文件的创建与管理、以及运行时的动态加载等。QML作为QT用于构建用户界面的声明式语言,也完全融入了这一国际化体系,让开发者能以简洁高效的方式实现界面的多语言切换。

实现步骤

在QT/QML应用中实现国际化(i18n)以支持中英文显示,主要涉及以下几个步骤:

1. 准备翻译文件

创建翻译文件:使用Qt Linguist工具(QT自带的工具)或手动创建.ts(Translation Source)文件。通常为每种语言创建一个,例如en.ts用于英语,zh.ts用于中文。

提取字符串:使用lupdate工具从源代码中提取可翻译的字符串到.ts文件中。这包括QML文件中的qsTr()或qsTranslate()包裹的文本。

2. 翻译字符串

翻译.ts文件:使用Qt Linguist工具(QT自带)或其他翻译工具编辑.ts文件,将英文字符串翻译成目标语言(如中文)。

编译.ts文件为.qm:使用lrelease工具将翻译好的.ts文件编译为二进制的.qm(Qt Message File)文件,这是运行时加载的文件。

3.设置应用程序语言

动态切换语言:可以通过修改QLocale或直接设置Application的语言来改变界面语言。

cmake 构建方式

生成Qt的ts翻译文件,编辑CMakeLists.txt文件,使用qt5_create_translation。

bash 复制代码
# 设置翻译源文件(.ts)的输出目录
#set(QML_FILES ${CMAKE_CURRENT_SOURCE_DIR}/source/qml/main.qml)
# 使用 file(GLOB ...) 获取所有 QML 文件
file(GLOB_RECURSE QML_FILES ${CMAKE_CURRENT_SOURCE_DIR}/source/qml/*.qml)
set(TS_FILES
        ${CMAKE_CURRENT_BINARY_DIR}/translations/daemon_en_US.ts
        ${CMAKE_CURRENT_BINARY_DIR}/translations/daemon_zh_CN.ts
        )

# 关键
find_package(Qt5LinguistTools)
qt5_create_translation(QM_FILES ${QML_FILES} ${TS_FILES} OPTIONS -source-language en_US -no-obsolete)

# 添加可执行文件
add_executable(${PROJECT_NAME} ${SOURCES} ${HEADERS} ${QML_FILES} ${QM_FILES})

注意,必须将 ${QM_FILES}加入到add_executable参数中才能在编译时生成只有原文的ts文件

ts文件会在"清除"或重新编译的时候一并被删除,再编译的时候生成全新的ts(原有的翻译会丢失,万分注意!!)

示例代码

假设您的 C++ 代码如下:

cpp 复制代码
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QTranslator>
#include <QLocale>
#include <QQmlContext>

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    // 创建翻译器对象
    QTranslator translator;

    // 初始化加载翻译文件(默认载入英文)
    translator.load(":/translations/daemon_en_US.qm");
    app.installTranslator(&translator);

    QQmlApplicationEngine engine;

    // 将翻译器对象设置到 QML 上下文环境中
    engine.rootContext()->setContextProperty("translator", &translator);
    engine.load(QUrl(QStringLiteral("qrc:/source/qml/main.qml")));

    return app.exec();
}

在 QML 文件中,假设您有如下内容:

javascript 复制代码
import QtQuick 2.12
import QtQuick.Controls 2.12

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Column {
        anchors.centerIn: parent
        spacing: 20

        Text {
            id: label
            text: qsTr("This is a text")
        }

        Button {
            text: "Switch to Chinese"
            onClicked: {
                // 动态切换到中文
                if (translator.load(":/translations/daemon_zh_CN.qm")) {
                    Qt.application.installTranslator(translator);
                    label.text = qsTr("This is a text");  // 触发翻译更新
                }
            }
        }

        Button {
            text: "Switch to English"
            onClicked: {
                // 动态切换到英文
                if (translator.load(":/translations/daemon_en_US.qm")) {
                    Qt.application.installTranslator(translator);
                    label.text = qsTr("This is a text");  // 触发翻译更新
                }
            }
        }
    }
}

在这个例子中,通过 engine.rootContext()->setContextProperty("translator", &translator); 这一行代码,QML 中的 translator 对象和 C++ 中的翻译器对象关联起来,使得 QML 中能够调用 C++ 的方法来动态加载翻译文件并自动更新界面显示的语言。

总结

通过将翻译器对象设置为 QML 上下文的属性,可以在 QML 中调用 translator 对象的函数,实现动态加载和切换翻译文件的功能,从而满足多语言动态切换的需求。

其中 engine.rootContext()->setContextProperty("translator", &translator); 的主要作用是将 C++ 对象暴露给 QML,以便在 QML 中直接使用和操控这个对象,使得多语言支持更具灵活性和动态性。

以下是一个将QML文件夹下的所有QML文件引入到CMakeLists.txt中的方法:

1. 使用 file(GLOB ...)

file(GLOB ...) 可以递归地获取指定目录下的所有符合条件的文件。这种方法非常灵活,适用于需要引入一组文件的场景。

bash 复制代码
cmake_minimum_required(VERSION 3.12)

project(daemon VERSION 1.0)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)

find_package(Qt5 COMPONENTS Core Quick LinguistTools REQUIRED)

# 设置源文件和头文件
set(SOURCES
    main.cpp
    source/cpp/myclass.cpp
)

set(HEADERS
    source/cpp/myclass.h
)

# 使用 file(GLOB ...) 获取所有 QML 文件
file(GLOB_RECURSE QML_FILES ${CMAKE_CURRENT_SOURCE_DIR}/source/qml/*.qml)

# 设置翻译文件
set(TS_FILES
    ${CMAKE_CURRENT_SOURCE_DIR}/translations/daemon_en_US.ts
    ${CMAKE_CURRENT_SOURCE_DIR}/translations/daemon_zh_CN.ts
)

# 创建翻译文件
qt5_create_translation(QM_FILES TS_FILES ${TS_FILES} QML_FILES ${QML_FILES})

# 添加可执行文件
add_executable(${PROJECT_NAME} ${SOURCES} ${HEADERS} ${QML_FILES} ${QM_FILES})

# 链接Qt库
target_link_libraries(${PROJECT_NAME} Qt5::Core Qt5::Quick)

在这个示例中:

  • file(GLOB_RECURSE QML_FILES ${CMAKE_CURRENT_SOURCE_DIR}/source/qml/*.qml):这一步使用通配符*.qml来递归获取source/qml目录下的所有QML文件,并将结果存储到QML_FILES变量中。
  • 剩余的CMake配置保留了引入其他源文件和头文件,以及Qt翻译文件的生成和处理。

2. 引入其他资源文件

如果您的QML项目中还有其他类型的资源文件(如图像文件、.js文件等),也可以使用类似的方法引入:

bash 复制代码
# 引入图像资源文件
file(GLOB_RECURSE IMAGE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/source/images/*)

# 引入JavaScript文件
file(GLOB_RECURSE JS_FILES ${CMAKE_CURRENT_SOURCE_DIR}/source/js/*.js)

将这些文件添加到目标中:

bash 复制代码
add_executable(${PROJECT_NAME} ${SOURCES} ${HEADERS} ${QML_FILES} ${QM_FILES} ${IMAGE_FILES} ${JS_FILES})

通过这种方式,可以灵活地管理和组织项目中的各种资源文件,简化CMake配置,确保正确引入所有需要的文件。

再次生成翻译文件

确保您的.ts文件已正确配置并包含在项目中。尝试手动运行lupdate命令并查看输出:

bash 复制代码
cd path_to_your_project
lupdate source/qml/*.qml source/cpp/*.cpp -ts translations/daemon_en_US.ts translations/daemon_zh_CN.ts

然后使用linguist工具打开.ts文件,确认其中是否包含待翻译文本:

bash 复制代码
linguist translations/daemon_zh_CN.ts

5. 手动更新和生成.qm文件

如果依旧遇到问题,可以尝试手动更新ts文件并生成qm文件,以确保流程正确:

bash 复制代码
# 手动更新 TS 文件
lupdate source/qml/*.qml source/cpp/*.cpp -ts translations/daemon_en_US.ts translations/daemon_zh_CN.ts

# 使用Qt Linguist工具编辑并保存 TS 文件
linguist translations/daemon_en_US.ts
linguist translations/daemon_zh_CN.ts

# 手动生成 QM 文件
lrelease translations/daemon_en_US.ts
lrelease translations/daemon_zh_CN.ts

在以上步骤中,验证所有QML和C++文件中确实包含带有qsTr()tr()的翻译标记,并确认lupdatelrelease工具的路径和执行是否正确。如果所有步骤正确完成,生成的.qm文件会包含预期的翻译数据。

注意:

lupdate工具本身不会自动进行翻译。它的主要功能是从源代码和QML文件中提取出所有标记为需要翻译的字符串,并生成或更新.ts文件。这些.ts文件是XML格式的翻译源文件,其中包含了需要翻译的原始字符串及其上下文信息,但并不会包含任何自动生成的翻译。

生成的.ts文件中所有翻译项最初都是未翻译状态,开发人员或翻译人员需要手动使用Qt Linguist工具为每个字符串提供翻译。

对于QML中的文本,应该使用qsTr()函数来包裹那些需要翻译的字符串。例如:

bash 复制代码
Text {
       text: qsTr("Hello, World!")
   }

在C++代码中,你应该使用tr()宏来标记需要翻译的字符串。例如:

cpp 复制代码
QString message = tr("Welcome to the application.");

确保所有的用户可见的字符串都通过tr()进行了包裹。这包括但不限于对话框消息、菜单项、按钮标签等。

避免在代码逻辑中使用硬编码的字符串:无论是QML还是C++,都应该避免直接在逻辑处理中使用未经qsTr()或tr()处理的字符串。如果字符串中包含变量或需要格式化的地方,使用占位符(如C++中的arg()方法或QML中的字符串插值)并确保翻译时考虑这些变量的存在。

qsTr()和tr()是分别在QML和C++中进行国际化的基本手段,通过它们确保字符串可以被翻译工具识别并处理。

总结:

  • lupdate 提取源字符串并生成 .ts 文件,不会自动翻译。
  • 使用 linguist 工具手动翻译 .ts 文件内容。
  • 使用 lrelease 生成 .qm 文件以供应用程序使用。

通过这个流程,您可以管理和使用Qt项目中的翻译文件,实现应用程序的多语言支持。

其他资源

https://www.cnblogs.com/Paoyao/p/15752116.html

https://zhuanlan.zhihu.com/p/379477970

配置CLion管理Qt项目国际化支持的方法_C 语言_脚本之家

Qt之Qml 国际化---实现简易语言切换功能_qml 中英文切换-CSDN博客

Qt / Qml 中支持多国语言_qml 多语言-CSDN博客

相关推荐
瓜牛_gn37 分钟前
mysql特性
数据库·mysql
奶糖趣多多2 小时前
Redis知识点
数据库·redis·缓存
CoderIsArt3 小时前
Redis的三种模式:主从模式,哨兵与集群模式
数据库·redis·缓存
师太,答应老衲吧5 小时前
SQL实战训练之,力扣:2020. 无流量的帐户数(递归)
数据库·sql·leetcode
Channing Lewis6 小时前
salesforce case可以新建一个roll up 字段,统计出这个case下的email数量吗
数据库·salesforce
毕业设计制作和分享7 小时前
ssm《数据库系统原理》课程平台的设计与实现+vue
前端·数据库·vue.js·oracle·mybatis
ketil277 小时前
Redis - String 字符串
数据库·redis·缓存
Hsu_kk8 小时前
MySQL 批量删除海量数据的几种方法
数据库·mysql
编程学无止境8 小时前
第02章 MySQL环境搭建
数据库·mysql
knight-n8 小时前
MYSQL库的操作
数据库·mysql