qt5-cmake-qml多语言实践

2023/12/09

Tags: Qt5 CMake Qml Translator

Table of Contents

1. 编码

1.1 CMake

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 添加引用Qt的名为LinguistTools的component
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core LinguistTools)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Gui Widgets Quick Qml QuickControls2 LinguistTools)

#定义需要生成的.ts ,放到TS_FILES这个cmake变量中
set(TS_FILES
    src/translations/zh_CN.ts
    src/translations/en_US.ts
    src/translations/ja_JP.ts )
    
#扫描这dv_app,dv_camera, dv_common这三个目录,把需要翻译的字符串扫描进.ts文件中
qt5_create_translation(QM_FILES 
${CMAKE_SOURCE_DIR}/dv_app 
${CMAKE_SOURCE_DIR}/dv_camera 
${CMAKE_SOURCE_DIR}/dv_common 
${TS_FILES} )

#在生成 xxx可执行文件时,把执行扫描生成.ts ,再把.ts生成.qm翻译二进制文件
add_library(xxx SHARED
  ${TS_FILES} #这一行只是为了在qt creator中看到.ts文件
  ${QM_FILES}
)

#复制翻译文件.qm到 生成目录的translations文件夹
add_custom_command(TARGET xxx POST_BUILD  COMMAND ${CMAKE_COMMAND} -E copy
    ${QM_FILES}
    $<TARGET_FILE_DIR:dv_common>/translations )
    

1.2. c++

1.2.1 简单封装加载qm翻译文件的逻辑

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
bool cpp_utility::load_language_qm(QString filePath)
{
    try
    {
        std::shared_ptr<QTranslator> translator =  prism::Container::get()->resolve_object<QTranslator>();
        if(!translator)
        {
            if(!QCoreApplication::removeTranslator(translator.get()))
            {
                std::shared_ptr<QTranslator> empty ;
                prism::Container::get()->register_instance(empty);
            }
            else
                throw std::string("卸载多语言翻译器失败");
        }

        if(!filePath.isEmpty())
        {
            std::shared_ptr<QTranslator> tr = std::make_shared<QTranslator>();
            if(tr->load(filePath))
            {
                if(QCoreApplication::installTranslator(tr.get()))
                    prism::Container::get()->register_instance(tr);
                else
                    throw std::string("安装多语言翻译器失败");

            }
            else
                throw std::string("加载多语言文件失败:") + filePath.toStdString();

        }
        else
        {
            qInfo()<<"正在卸载非中文的多语言翻译器";
        }
        //通知qml engine,如果有的话
        std::shared_ptr<QQmlApplicationEngine> engine = Container::get()->resolve_object<QQmlApplicationEngine>();
        if(engine)
            engine->retranslate();
    }
    catch(std::string & mes)
    {
        qCritical()<< QString::fromStdString(mes);
        return false;
    }
    return true;
}

上面这个c++方法,即被放到ioc容器中,又被注册到qml engine,所以c++和qml中都可以直接调用,只需要传入一个qm的文件路径,就可以加载,并在加载完成后通知qml engine刷新ui 。

通知的这段逻辑需要qt版本至少qt 5.10

1.3 调用

3.怎么让项目中的字符串被扫描到 .ts文件中

在qml中

1
2
3
Text{
    text: qsTr("惨惨字字,将被扫描到.ts文件中,任人翻译")
}

在c++中

1
qDebug() << QObject::tr("卑微字字,将被扫描到.ts文件中,任人翻译"); 

4. 怎么使用qt 小工具翻译

image-20231209171941103

image-20231209172021960

没有翻译完,软件也不会报错,只是会在切换语言时,不会变更相关的翻译

例如有一个需要翻译的文字[“黄滨滨”]中文翻译为[“靓仔”],英语翻译为[“huangbinbin”]完了,但是日语没有翻译,

这时中文情况下显示[“靓仔”],

切换英文后应会显示[“huangbinbin”]

切换日语后,由于 没有翻译,会导致仍然显示[“huangbinbin”],

并不是像你直觉的那样,仍然显示[“黄滨滨”]

*. 注意事项

*.1 首次生成 .ts,需要设置一下语言

image-20231209164936900

第三行中, language需要正确设置为BCP 47规范中的<小写国家>_<大写地区>,之后生成的.qm文件,才能被加载到qt 程序中,否则会报错.

常用的语言

更多参阅 Language Tags (BCP 47)

>> Home

Comments