开发者

一文详解如何实现QT的多语言切换(静态+动态)

开发者 https://www.devze.com 2024-08-14 11:46 出处:网络 作者: Ellie是个昵称
目录背景:任务:一、QT语言家1、.pro文件增加TRANSLATIONS2、更新翻译(lupdate)3、通过QT语言家打开.ts文件4、代码中使用.qm文件进行翻译5、需要注意的问题二、.ts文件的手动编写1、.ts的格式说明2、多人管理开发
目录
  • 背景:
  • 任务:
  • 一、QT语言家
    • 1、.pro文件增加TRANSLATIONS
    • 2、更新翻译(lupdate)
    • 3、通过QT语言家打开.ts文件
    • 4、代码中使用.qm文件进行翻译
    • 5、需要注意的问题
  • 二、.ts文件的手动编写
    • 1、.ts的格式说明
    • 2、多人管理开发
    • 3、代码中如何使用
  • 总结

    背景:

    1.项目开发上:多人多模块同时开发,需要考虑如何便于管理共同开发

    2.文本有两类:界面上固定不变的文本(静态);在程序运行时才能获得的文本(动态)

    任务:

    实现软件的多语言切换功能。

    接下来会介绍两个实现途径,分别是QT语言家工具,以及.ts文件的手动编写(推荐第二种)。

    一、QT语言家

    Qt Linguist(Qt 语言家)是 Qt 开发环境中用于国际化和本地化的工具。它会提供翻译支持,将应用程序的用户界面和其他文本元素翻译成不同的语言,是一种可视化工具。

    如果安装了的话,可以在这里找到:

    一文详解如何实现QT的多语言切换(静态+动态)

    1、.pro文件增加TRANSLATIONS

    TRANSLATIONS += resource/language/lang_zh_CN.ts\
                    resource/language/lang_en.ts
    说明:
    lang_zh_CN.ts为中文部分,lang_en.ts为英文部分,
    此处我的这两个.ts文件是放在resource/language目录下,需要照自己的具体路径进行更改
    

    2、更新翻译(lupdate)

    一文详解如何实现QT的多语言切换(静态+动态)

    之后出现信息:

    一文详解如何实现QT的多语言切换(静态+动态)

    3、通过QT语言家打开.ts文件

    一文详解如何实现QT的多语言切换(静态+动态)

    由于我使用的是MSVC 2017 64-bit,所以我是使用对应的Linguist打开两个.ts文件:

    一文详解如何实现QT的多语言切换(静态+动态)

    一文详解如何实现QT的多语言切换(静态+动态)

    在这两项中分别写入英文文本和中文文本,编辑完成后保存并发布(lrelease):

    一文详解如何实现QT的多语言切换(静态+动态)

    发布(lrelease)的目的是将.ts文件编译为.qm文件,.qm文件是二进制文件,可以看到同目录下已经生成.qm文件:

    一文详解如何实现QT的多语言切换(静态+动态)

    4、代码中使用.qm文件进行翻译

    将生成的.qm文件加入到资源文件中。

    在启动时根据不同的系统语言显示不同的翻译:

    void MainWindow::initLanguage()
    {
        QTranslator translator;
        QLocale::Language lab = QLocale::system().language();
        if(QLocale::Chinese == lab)
        {
            translator.load(":/language/lang_zhttp://www.devze.comh_CN.qm");
            hApp->installTrans编程客栈lator(&translator);
            Q_EMIT hApp->m_sigmanager->translateLanguage(LANGUAGE::CHINESE);
        }else if(QLocale::English== lab){
            translator.load(":/language/lang_en.qm");
            hApp->installTranslator(&translator);
            Q_EMIT hApp->m_sigmanager->translateLanguage(LANGUAGE::ENGLISH);
        }
    }
    
    说明:
    注意.qm文件的路径要写对,不然无法翻译,如果找不到可以在.pro文件中增加 INCLUDEPATH
    这里我自定义了translateLanguage信号去触发语言的切换,各个模块负责分别连接该信号,编写槽函数,举例:
    某模块:
    connect(hApp->m_sigmanager,&SignalManager::translateLanguage,this,&SampleMainWidget::retranslate);
    voandroidid SampleMainWidget::retranslate()
    {
        ui->retranslateUi(this);
    }
    

    5、需要注意的问题

    QT语言家不止可以展示.ui文件中我们给控件预先编辑的文本内容,还有代码中定义的文本内容,只是需要在QT语言家展示代码内待翻译文本,要使用宏 QT_TR_NOOP ,它通常用于标记那些在运行时不需要翻译,但需要在翻译文件中保留的字符串。

    QString test = QT_TR_NOOP("test1")
    
    说明:
    test的值仍然是原文本,而非翻译后的文本
    

    在需要翻译时,使用以下方式(在retranslateui后需要重新设置控件文本):

    void SampleMainWidget::retranslate()
    {
        ui->retranslateUi(this);
        QString text = ui->rackBtn->text();
        ui->rackBtn->setText(hApp->translate("SampleApply",text.toStdString().c_str()));
    }
    说明:
    hApp->translate中的第一个参数,其实对应.ts文件中的<name>元素,和作用域的作用类似
    如果使用QT语言家,一般是QT_TR_NOOP定义文本所在的类名
    第二个参数,其实对应.ts文件中的<source>元素,这里的类型是char*
    

    二、.ts文件的手动编写

    首先需要简单了解.ts文件和.qm文件:

    • .ts文件(翻译源文件):.ts文件是Qt中的翻译源文件,XML格式。它包含了源代码中的所有可翻译文本,以及它们的上下文信息。

    • .qm文件(翻译目标文件):.qm文件是Qt中的翻译目标文件,二进制格式。.qm文件包含了已经翻译好的文本,以及与之对应的源代码中的文本。通过将.ts文件编译成.qm文件,可以提高程序的执行效率,因为程序在运行时直接加载.qm文件,而无需解析和处理XML格式的.ts文件。

    1、.ts的格式说明

    打开.ts文件:

    一文详解如何实现QT的多语言切换(静态+动态)

    如图中标号所示:

    1、文件头部信息。指定了翻译文件的版本(2.1),目标语言(zh_CN,即中文)等信息。

    2、划分的作用域名字。

    3、每个待翻译的字符串都有一个 message 元素,其中location元素指定了源代码中字符串的位置;source 元素包含了原始的文本;translation元素用于存储翻译后的文本。

    其中,location没有也可以,只是QT语言家打开.ts文件时定位不到字符串位置而已,主要还是source 元素和translation元素,source元素相当于字符串的id,翻译家通过source在lang_zh_CN.ts找中文文本,在lang_en.ts找英文文本。

    2、多人管理开发

    创建language.xlsx,language.xlsx中包含多个模块sheet,每个sheet的表头为 id Chinese English

    其中id为文本项唯一标识符,Chinese为中文文本,English为英文文本。

    一文详解如何实现QT的多语言切换(静态+动态)

    使用python,将excel转换为.ts文件,并编译为.qm文件:

    import openpyxl
    import subprocess
    from xml.dom.minidom import Document
    
    
    def read_excel(file_path):
        # 打开 Excel 文件
        wb = openpyxl.load_workbook(file_path)
        
        # 读取所有 sheet 的数据
        all_rows = []
        for sheet_name in wb.sheetnames:
            sheet = wb[sheet_name]
            all_rows.extend([
                tuple(sheet.cell(row=row, column=col).value for col in range(1, sheet.max_column + 1))
                for row in range(2, sheet.max_row + 1)
            ])
    
        return all_rows
    
    
    def create_ts_file(language, rows):
        # 创建 XML 文档
        doc = Document()
        ts = doc.createElement('TS')
        ts.setAttribute('version', '2.1')
        ts.setAttribute('language', language)
        doc.appendChild(ts)
        
        # 创建 <context> 元素
        context = doc.createElement('context')
        ts.appendChild(context)
    
        for row in rows:
            source, chinese, english = row
    
            # 创建 <message> 元素
            message = doc.createElement('message')
    
            # 创建 <source> 元素
            source_element = doc.createElement('source')
            source_element.appendChild(doc.createTextNode(source))
            message.a编程客栈ppendChild(source_element)
    
            # 创建 <translation> 元素
            translation_element = doc.createElement('translation')
            translation_element.appendChild(doc.createTextNode(chinese if language == 'zh_CN' else english))
            message.appendChild(translation_element)
    
            context.appendChild(message)
    
        # 将 XML 写入文件,设置缩进和换行
        xml_str = doc.toprettyxml(indent="    ", encoding='utf-8').decode('utf-8')
        ts_file_path = f'lang_{language}.ts'
        with open(ts_file_path, 'w', encoding='utf-8') as file:
            file.write(xml_str)
            
        # 调用 lrelease 命令编译 .ts 文件为 .qm 文件
        subprocess.run(['lrelease', ts_file_path])
    
    if __name__ == "__main__":
        # 读取 Excel 文件数据
        excel_data = read_excel("language.xlsx")
    
        for language in ["zh_CN", "en"]:
            # 生成每个语言的 .ts 文件
            create_ts_file(language, excel_data)
    
    

    以下为生成的内容格式:

    一文详解如何实现QT的多语言切换(静态+动态)

    思路:

    将工程所有文本都集中在一个excel中,需要给专业翻译人员翻译时,只需要提供这样一份excel,在指定位置补充翻译后文本就可以。

    这里是简单通过id的数值范围使各模块独立,即每个sheet的文本容量为1万,从左到右:main(0到9999),scheme(10000到19999),sample(20000到29999)…以此类推。

    也可以通过sheet名称作为作用域名称,在.ts文件中增加name元素,只要能保证source唯一不重复,这些方式都是可以的。

    3、代码中如何使用

    在代码中的使用(可以不使用ui->retranslateUi(this);了):

    在连接语言切换信号的槽函数中设置待翻译的文本信息,如:

    void SampleMainWidget::retranslate()
    {
        ui->rackBtn->setText(hApp->translate(0,"0_main_voice"));
    }
    

    translate参数中0代表全局范围,"0_main_voice"即文本id。

    总结

    到此这篇关于如何实现QT的多语言切换(静态+动态)的文章就介绍到这了,更多相关QT多语言切换实现内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支python持编程客栈(www.devze.com)!

    0

    精彩评论

    暂无评论...
    验证码 换一张
    取 消