1. 说明

早在去年4月份就发过一篇文章讲界面汉化的思路(《汉化过程和思路》)。文章里面提到过两种方法:

第一种是添加#pragma,然后将字符串强编码为中文;

第二种是通过脚本批量替换代码中的字符串,并修改错误后,通过Qt的语言家来汉化。

第一种办法最痛苦,因为要替换所有字符串为中文,并且界面Ui也需要手动修改为中文才能实现界面汉化,工作量巨大不考虑。

第二种办法是为了沿用Qt语言家的优势来做翻译。在代码中的字符串只需要用tr进行包裹,然后在加载qm文件后就能实现汉化了。但是我给出的脚本替换方法并不能正确替换所有字符串为tr包裹,会造成需要修改的代码很多,因此我发文后也没有进一步去做汉化的尝试了。本文也不再使用以前提到的脚本批量替换字符串了,而是手动将代码中的字符串通过tr进行包裹,然后使用语言家来扫描代码,提取字符串进行翻译。废话也不多说了,先看视频: 

2. 前置处理

2.1. ui文件

afsim中ui界面的字符串,可直接通过lupdate提取到ts文件,所以可先对ui文件进行汉化。

 从上图可以看到,光是提取ui文件中的需要翻译的字符串就有2700多个,人工逐条翻译是很难受的,可直接将ts文件喂给deepseek。

注:如果只对ui文件翻译后是不能直接使用的,用的话会启动直接崩溃。

原因是WkfMainWindow.ui的菜单项如File、Tools等,在afsim的代码中是以下图方式获取QMenu指针的,如果ui翻译为中文了,那么返回的指针会为空:

所以需要将上图的Tools用QObject::tr进行包围后才能返回正确的指针。

2.2. 代码中的字符串

代码有很多的字符串都是直接写的,对于这类字符串只能通过翻代码一条一条的添加QObject::tr包围,工作量也挺大的,比如下面这个Action:

我目前完成了warlock全部、mystic部分、wizard部分代码文件中界面显示的字符串处理,已经有6000多条了,而且还不是全部的。

2.3. QObject支持

有些项目工程因为没有链接Qt库,因此在引入QObject时会报错,这里需要修改CMakeList.txt文件添加Qt可以的支持:

#  添加Qt支持
set(SWDEV_QT_PACKAGE "qt-5.12.11" CACHE STRING "" FORCE)
mark_as_advanced(FORCE SWDEV_QT_PACKAGE)
swdev_acquire_packages(${CMAKE_CURRENT_SOURCE_DIR} ${SWDEV_QT_PACKAGE})
######################

#  添加Qt支持
# Include macros and configuration to support builds of Qt projects
file(GLOB QRC ui/resources/*.qrc)
file(GLOB UIS ui/*.ui)
include(qt_project)
configure_qt_project(UI UI_HEADERS ${UIS})

# Install required qt core libs
install_qt_libs_all()
install_qt_plugins(${INSTALL_EXE_PATH}/qt_plugins)
install_qt_licenses()

# install 3rd_party-cmake files that are required to build mover creator not covered elsewhere
install_source_files(${TOOLS_DIRECTORY}/3rd_party-cmake/config.cmake
                     ${TOOLS_DIRECTORY}/3rd_party-cmake/shared.cmake
                     ${TOOLS_DIRECTORY}/3rd_party-cmake/${SWDEV_QT_PACKAGE}.cmake
                     tools/3rd_party-cmake
                    )

2.4. 静态常量处理

在afsim代码中有一些界面要展示的字符串是通过静态常量进行定义的,这种字符串之前说过Qt无法在运行时获取翻译结果,也不能修改为静态变量(会报无法解析的外部符号),因此没有办法使用QObject::tr包围,只能修改代码,让其在运行时返回。下面以warlock的PlatformData插件中PlatformDataUpdaters.hpp中的此类变量为例说明:

原文中的字符串为左侧代码,我将其修改为了静态函数,并在静态函数中通过静态变量包围后返回来达到翻译的目的:

修改后还需要将之前引用的cUPDATER_NAME静态变量修改为引用cUPDATER_NAME()静态函数调用。

2.5. 输出处理

通过QObject::包围汉化的中文在输出到windows的控制台上时会出现乱码,如std::cout,ut::log等的输出。由于这种输出既可以默认为控制台,也可以输出到Qt的界面上,因此不管使用toStdString还是toLocal8Bit都会有一方出现乱码。我这里的处理方式是通过dynamic_cast转换QCoreApplication::instance()来判空确定是控制台程序函数GUI程序,,再来决定使用哪种转换(仅供参考)。对wizard需要做进一步单独处理,因为他是独立启动mission来输出到界面,如果不处理,界面会是乱码:

static bool isWizardRun = false;

Void UT_EXPORT UtUtil::setIsWizardRun()
{
    isWizardRun = true;
}
const std::string UT_EXPORT UtUtil::UtToStd(const QString& qstring)
{
    static std::string ret;
    if (isWizardRun)
    {
        ret = qstring.toStdString();
    }
    else
    {
        QGuiApplication* app = dynamic_cast<QGuiApplication*>(QCoreApplication::instance());
        if (app == nullptr)
        {// 控制台
            ret = qstring.toLocal8Bit().data();
        }
        else
        {// GUI
            ret = qstring.toStdString();
        }
    }
    return ret;
}

另外,这里也不能直接在mission程序代码的main中直接调用,那样会造成直接用mission时中文乱码,我的处理方式是添加一个命令行参数-isWizardRun,并在wizard启动mission时将这个参数添加进去,这样就能自动适配wizard启动mission和mission独立启动都能正确显示中文的问题。

2.6. 界面反查

每个代码文件都一一查看并添加QObject::tr其实挺枯燥的,还有一种比较好玩的方式是运行程序,查看界面上的英文,然后到源码中全文查找和替换。这样可能会轻松点,毕竟一次可以替换好多重复的但分布在不同文件中的字符串。

3. 汉化

上面的处理完成后,就可按下面的步骤来进行汉化了。

3.1. lupdate 生成ts文件

通过Qt自带的命令行工具定位到afsim源代码src目录下。执行以下命令:

lupdate swdev/src -ts afsim2.9_zh_CN.ts

完成后会生成ts文件,此文件将源代码中所有ui文件及QObject::tr包围的字符串进行了提取并保存。

3.2. Linguist打开ts文件

Linguist工具可以读取ts文件进行专业的翻译,后期也可以对照着界面修改翻译,翻译完成后再发布qm文件替换原来的就行。

图片-qveR.png

 PS:将ts文件直接丢给deepseek,坐收渔利吧!!!

3.3. qm文件加载

Linguist工具翻译后,选择发布,会在ts相同目录下生成qm文件,将qm文件放到运行目录下,就可以在创建QCoreApplication或QApplication后,通过以下代码加载:

QCoreApplication qtapp(argc, argv);
QTranslator t;
t.load(qtapp.applicationDirPath() + "/../translator/afsim2.9_zh_CN.qm");
qtapp.installTranslator(&t);

另外,有些对话框如颜色选择、字体选择对话框是Qt自带的,需要再安装Qt自带的qt_zh_CN.qm文件即可实现这类对话框的汉化。

4. 后记

上面的汉化处理方式即是我目前在用的,目前来说对Ui界面的汉化应该有一半多了。相对来说之前那篇文章的汉化思路,本文的方式工作量就不是那么大了,至少不用太多考虑逻辑问题。另外,mover_creator由于涉及到非常多专业名称,未能完全汉化。

此汉化结果我也同步更新到我的某宝某鱼脚本编辑的中文支持产品中,也算是将中文化进一步升了一下级,购买过的朋友可直接下载更新^_^,下面的码是只有界面汉化的:

往期推荐

外部数据统一接入分发中间件

天线方向图实时绘制插件

基于wsf插件扩展内置platform

docker搭建麒麟V10上afsim编译、开发和运行环境

文末二维码.png