分享我在编程中的设计观念,遇到的技术点,让我们在工作和生活中一起追求自由

这几年,自由的概念让我印象深刻,前不久看到一个词叫辞职自由。

别人在实现财务自由的时候,我在追求加班自由,架构让我们自由。

软件开发中的多语言

多语言也称作国际化支持,在企业级软件中,多国语言支持是必不可少的部分,我们的Qt项目,使用Qt Linguist实现多国语言显示。

我将从多语言Key定义、上下文、多语言Key收集、生成翻译文件几个方面,给大家介绍项目中Qt Linguist的工程化实现,它包含的组件如下图。

大语言模型 多轮对话_大语言模型 多轮对话

多语言Key定义

多语言Key是多种语言的标识,软件中通过此Key,转换成目标语言,通常多语言Key定义使用英文字符串表示。

项目中,首先需要在源码或ui等配置文件中,按照规则增加多语言Key。

源码中用tr定义多语言Key,也可以使用宏定义QT_TR_NOOP / QT_TRANSLATE_NOOP做前置标记。源码中,如果类不是QObject派生,可以使用QObject::tr静态函数,或Q_DECLARE_TR_FUNCTIONS()宏。

大语言模型 多轮对话_多语言_02

ui文件中,控件的caption会作为多语言Key,不需要额外处理。同时注意:ui中不要使用中文。

xml中不支持配置多语言Key,但测量、功能项等配置文件,涉及定义多语言Key的需求,后续我们会通过ScriptTool自定义规则,将xml中caption解析到h/cpp源码文件中,以支持多语言Key标记。

多语言上下文

源码中多语言Key定义时,当前的类名称作上下文;比如QObject::tr(“name”), QObject就是name的上下文。

在Qt中,同一个Key在不同上下文中翻译可以不同。

我们的软件超声软件项目中,定义了全局上下文,为“LTranslatorsDefine”;某些解析不到的Key,和配置文件解析的Key,我们使用LTranslatorsDefine作为上下文。

针对全局上下文的场景,我们做了特殊处理。

定义了从QObject派生的LTranslatorsDefine类,类中可以使用QT_TR_NOOP宏标记多语言Key,解析不到的Key,我们可以定义在此类中。同时,在系统初始化时,注册了自定义的QTranslator对象。

boolLLanguageManagerPrivate::loadLanguageMap(){    QCoreApplication::processEvents();    //多语言数据加载    QTranslator* qtTranslator = new QTranslator(q);    LTranslatorDecorator* lmTranslator = new LTranslatorDecorator(qtTranslator, qtTranslator);      boolb_ret = qtTranslator->load(currentLanguage, g_ufConfig->languagePath());    b_ret = b_ret&&QCoreApplication::installTranslator(lmTranslator);    return b_ret;}

LTranslatorDecorator是系统默认QTranslator对象的“装饰者”,它的功能就是在系统默认QTranslator查找不到当前上下文时,去全局上下文LTranslatorsDefine中查找Key,像这样。

LTranslatorDecorator::LTranslatorDecorator(QTranslator* component, QObject *parent)  : QTranslator(parent)  , m_pComponent(component){  if(m_pComponent.isNull())  {    qFatal("LTranslatorDecorator component is null.");  }}QString LTranslatorDecorator::translate(const char *context, const char *sourceText, const char *disambiguation, int n) const{  QByteArrayList vContect = {    context,    "LTranslatorsDefine",  };  QString transStr;  for (auto con : vContect)  {    transStr = m_pComponent->translate(con.data(), sourceText, disambiguation, n);    if (!transStr.isNull())    {      break;    }  }  return transStr;}

如果当前上下文、全局上下文都没有查询到翻译,则返回Key字符串作为显示字符。

多语言Key收集

多语言Key定义在ts文件中,项目时,通常需要同时收集多个工程的源码,使用lupdate可以满足这个需求。

我们写了个批处理脚本,调用Qt的lupdate生成ts文件,像这样。

set scan_path= ^ ./resource/ui ^ ./src/ultrasonicbusiness/src ^ ./src/ultrasonicui/src ^ ./src/base/src ^ ./src/product/srclupdate -disable-heuristic number -no-obsolete -no-ui-lines -extensions ui,c,cpp,h,qs,qml %scan_path% -ts resource/language/zh_CN.ts -target-language zh_CNlupdate -disable-heuristic number -no-obsolete -no-ui-lines -extensions ui,c,cpp,h,qs,qml %scan_path% -ts resource/language/en.ts -target-language en

多语言翻译

使用Qt语言家(linguist.exe )打开收集脚本生成的ts文件。

从左侧上下文列表中选择上下文,然后在字符串子窗口中选中翻译的Key,输入或者选择已有翻译,翻译确定后点击字符Key左侧更改翻译状态,接受翻译。

大语言模型 多轮对话_大语言模型 多轮对话_03

翻译修改完成后,选择文件->发布,生成qm文件,qm文件是多语言资源文件,也就是系统初始化QTranslator需要load的文件。

大语言模型 多轮对话_qt语言家使用_04

Qt语言家的使用,在Qt助手中搜索关键字:

Qt Linguist Manual: Translators

原则

Qt助手关键字:Writing Source Code for Translation

1、字符使用QString类型,支持UTF-8编码;

2、所有可显示标题,使用tr。