Qt C++ 多语言高阶实现:程序启动自动编译 .ts 文件并生成语言菜单

(简单地说,就是让 Qt C++ 程序在启动时自动搜索编译.ts文件,并自动生成语言菜单,实现多语言实时切换)

目录


第一部分_需求背景与实现目标

实际需求痛点

在 Qt C++ 开发中,国际化多语言切换通常需要提前编译 .ts 文件生成 .qm 文件,并随程序一同发布。然而,这种方式存在以下局限性:

  1. 每次修改发布都需要预先编译qm文件。
  2. 无法直接修改或更新已有的语言文件。(需要借助linguist等工具)
  3. 用户无法扩展新的语言支持,必须求助开发者。

返回目录


本视频实现目标

本视频将利用 Qt C++ 内置的多语言解决方案,不依赖任何第三方库,简洁高效地实现以下功能:

  1. 程序启动时自动编译 .ts 文件为 .qm 文件。
  2. 搜索 .qm 文件动态生成语言菜单。
  3. 实现多语言的实时动态切换,无需重启程序。

这样,程序发布后用户便可以自由修改或新增语言文件,大大提升程序的实用性和扩展性。

Image 2 Image 3

返回目录


本视频相关资料

通过一个简单的例子,讲解实现这些功能的核心知识和操作方法。视频时长控制在 40 分钟内,后续将提供完整的讲解资料和源代码。请用户注意:在gitee.com创建项目时,它自作主张将LangTest04改为lang-test04,所以从 https://gitee.com/patton88/lang-test04.git 下载克隆的项目目录为lang-test04,用户必须将其改为langtest04,项目才能正常编译运行。

如果本视频对您有所帮助,希望大家点赞、关注、收藏!您的支持是作者继续制作更好内容的动力!

注意:抖音视频有问题,请大家观看B站视频

返回目录


第二部分_具体实现过程

传统多语言切换演示_基础项目搭建

  1. 传统多语言切换演示(参见上期视频)
    传统方式实现多语言切换,用户通过按钮选择语言,程序加载对应的 .qm 文件并更新界面语言。
    传统方式需要提前编译 .ts 文件,无法直接更新语言文件,用户无法扩展语言支持。
    参见上期视频。相关资料:

  2. 扩展目标:在上述传统项目基础上,搭建 LangTest04、已添加窗口组件布局,进一步实现程序启动时自动编译 .ts 文件,动态生成语言菜单,实现动态扩展语言支持。

返回目录


高阶实现_程序启动时自动编译ts文件

  1. 核心功能
    在程序启动时,自动搜索 res/language 目录中的 .ts 文件,并调用 lrelease.exe 将其编译为 .qm 文件。

  2. 代码实现
    mainwindow.cppinitLanguageMenu 函数中:

    void MainWindow::initLanguageMenu() {
        // 指定 .ts 文件路径,搜索获取 .ts 文件列表
        QDir languageDir("res/language");
        QStringList tsFileList = languageDir.entryList(QStringList("*.ts"), QDir::Files);
        QStringList tsFilePathList;
        for (const QString &tsFile : tsFileList) {
            tsFilePathList.append(languageDir.filePath(tsFile));
        }
    
        // 调用 lrelease.exe 编译 .ts 文件列表
        QProcess *process = new QProcess(this);
        process->start("res/lrelease/lrelease.exe", tsFilePathList);
    
        // 连接编译完成信号。必须等待 .qm 文件编译完成后,才能搜索 .qm 文件动态生成语言菜单
        connect(process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
                this, [this, process]() {
                    if (process->exitStatus() == QProcess::NormalExit && process->exitCode() == 0) {
                        this->onCompileTsFilesFinished();
                    }
                    process->deleteLater();
                });
    }
    
  3. 关键点

    • 使用 QProcess 调用 lrelease.exe 自动编译 .ts 文件。
    • 必须等待 .qm 文件编译完成后,才能调用 onCompileTsFilesFinished 函数,才能搜索 .qm 文件动态生成语言菜单。

返回目录


高阶实现_动态生成语言菜单

  1. 功能描述
    搜索 .qm 文件,动态生成语言菜单,并为每个菜单项绑定对应的语言切换功能。

  2. 用Lambda表达式为语言菜单动态添加槽函数
    onCompileTsFilesFinished 函数中:

    // 等待 .qm 文件编译完成调用
    void MainWindow::onCompileTsFilesFinished() {
        QMenuBar *menuBar = this->menuBar();
        QMenu *languageMenu = menuBar->addMenu(tr("语言"));
    
        // 搜索获取 .qm 文件列表 qmFiles
        QDir languageDir("res/language");
        QStringList qmFiles = languageDir.entryList(QStringList("*.qm"), QDir::Files);
    
        // 动态生成语言菜单
        for (const QString &qmFile : qmFiles) {
            QString languageName = extractLanguageName(qmFile);
            QAction *action = new QAction(languageName, this);
            action->setCheckable(true);
            languageMenu->addAction(action);
    
            // 用Lambda表达式为语言菜单动态添加槽函数
            connect(action, &QAction::triggered, this, [this, qmFile]() {
                changeLanguage(qmFile);
            });
        }
    }
    
  3. 提取语言名称
    使用 extractLanguageName 函数从 .qm 文件名中提取语言名称:

    QString MainWindow::extractLanguageName(const QString &qmFile) {
        QMap<QString, QString> mapLanguage = {
            {"_zh_CN", tr("简体中文")}, {"_en", tr("英文")}, {"_fr", tr("法语")},
            {"_de", tr("德语")}, {"_ja", tr("日语")}
        };
        for (auto it = mapLanguage.begin(); it != mapLanguage.end(); ++it) {
            if (qmFile.contains(it.key())) {
                return it.value();
            }
        }
        return qmFile;
    }
    

返回目录


实现多语言动态切换

  1. 切换语言的核心逻辑
    changeLanguage 函数中:

    void MainWindow::changeLanguage(const QString &qmFile) {
        if (translator) {
            qApp->removeTranslator(translator);
            delete translator;
        }
    
        translator = new QTranslator(this);
        if (translator->load("res/language/" + qmFile)) {
            qApp->installTranslator(translator);
        }
    
        retranslateUi();
    }
    
  2. 刷新界面语言
    retranslateUi 函数中:

    void MainWindow::retranslateUi() {
        ui->retranslateUi(this);
        QString strLang = tr("当前语言是");
        ui->label_3->setText(strLang + extractLanguageName(currentLanguageQm));
    }
    

返回目录

保存用户语言选择_重启程序后自动切换用户选择语言

  1. 准备配置文件,加载用户语言选择
    MainWindow 函数中处理配置文件:

    MainWindow::MainWindow(QWidget *parent)
       : QMainWindow(parent), ui(new Ui::MainWindow) {
       ui->setupUi(this);
    
       // 1、处理配置文件
       // Qt中使用QSettings类读写ini文件,第一个参数是ini文件路径,第二个参数表示是ini文件格式,第三个参数可省略
       settingsFile = new QSettings(QCoreApplication::applicationName() + ".ini",
                                     QSettings::IniFormat, this);
       // 解决QSettings保存中文值,ini自动保存为ANSI、GB2312格式后,启动崩溃问题
       settingsFile->setIniCodec(QTextCodec::codecForName("GBK"));
    
       // 加载用户语言选择
       currentLanguageQm =
          settingsFile->value("Main/strCurrentLanguageQm", "").toString();
    
       // 2、初始化语言菜单
       initLanguageMenu();
    }
    
  2. 保存用户语言选择
    retranslateUi 函数中保存当前语言 qm 文件名称:

    // 更新界面语言
    void MainWindow::retranslateUi() {
       // ......
    
       // 保存当前语言 qm 文件名称
       settingsFile->setValue("Main/strCurrentLanguageQm", currentLanguageQm);
    
       // ......
    }
    

返回目录


第三部分_用户自行修改或新增语言支持

通过以上方式,我们便实现本视频的目标,让 Qt C++ 程序在启动时自动编译.ts文件,自动生成语言菜单,实现多语言实时切换。
这样,程序发布后用户便可以自由修改或新增语言文件,大大提升程序的实用性和扩展性。


演示修改.ts文件后-重启程序立即生效

用文本编辑器打开.ts,修改LangTest04_fr.ts文件中的内容,比如修改为:

<message>
   <location filename="../../../../mainwindow.cpp" line="189"/>
   <source>QT多语言演示程序。当前语言是</source>
   <translation>QT5 multi Language sample program. Current language is </translation>
</message>

保存修改结果,重启程序立即生效。

返回目录


演示添加法语支持

  1. 创建法语 .ts 文件
    在项目的 LangTest04.pro 文件中,添加法语 .ts 文件的配置:

    TRANSLATIONS += LangTest04_fr_FR.ts
    
  2. 生成 .ts 文件
    使用 lupdate 命令生成新的 .ts 文件:

    lupdate LangTest04.pro -ts res/language/LangTest04_fr_FR.ts
    
  3. 翻译内容

    • 使用 Qt Linguist 打开 LangTest04_fr_FR.ts 文件,翻译所需内容并保存。
    • 可以用文本编辑器打开.ts,直接进行修改。
    • 较大量的翻译,可以借助工具、AI、python等方式完成。
  4. 编译 .ts 文件为 .qm 文件
    程序启动时会自动编译 LangTest04_fr_FR.tsLangTest04_fr_FR.qm,并在语言菜单中显示法语选项。

返回目录


第四部分_安全性优化指南

如果开发者担心QT程序发布时,直接发布.ts文件,可能会影响程序安全性。
开发者可以删除.ts文件中的所有location标签等信息,注意name等标签不能删。
可以使用Python、AI工具、正则表达式等方式进行删除。

生成正则表达式

比如,用正则表达式删除所有location标签,
现在方法很简单,只需将要求发给deepseek、chatGPT、kimi等AI,AI便可返回所需结果,还有相应解释。
通过简单的修改测试,便能实现我们的需求。

删除所有location标签的正则表达式

<location filename="../../../../mainwindow.ui" line="14"/>
^\s*<location filename="[^"]*" line="\d+"\/>\s*\r?\n

正则表达式解释

  • ^\s*: 匹配行首后的多个空白字符(包括空格和制表符)。

  • <location filename=": 匹配字符串的开头部分。

  • [^"]*: 匹配引号内的任意字符,直到遇到下一个引号。

  • " line=": 匹配中间的固定部分。

  • \d+: 匹配一个或多个数字。

  • \/>: 匹配结束的 "/>

  • \r?\n: 匹配回车换行符。

    用文本编辑器打开.ts文件,搜素删除所有location,保存修改结果,重启程序立即生效。

返回目录


总结与注意事项

  1. 总结

    • 通过本视频的讲解,我们成功实现了一个具有高扩展性和实用性的多语言动态切换功能。
    • 用户可以自由修改或新增语言文件,而无需依赖开发者。
    • 这种设计方式不仅简化了开发流程,还极大地提升了程序的实用型和灵活性。
  2. 实现效果

    • 程序启动时自动编译 .ts 文件生成 .qm 文件。
    • 根据 .qm 文件动态生成语言菜单。
    • 用户选择语言后,界面实时切换,无需重启程序。
    • 可以实现保存用户语言选择,重启程序后自动切换用户选择语言。
    • 用户可以自行修改.ts语言文件,扩展新的语言支持。
  3. 注意事项

    • 关键:确保 lrelease.exe.ts 文件路径正确。
    • 关键:确保 .ts 格式正确,建议使用 Qt Linguist 工具检查。
    • 用户新增语言,只支持 extractLanguageName 函数中映射表中的语言。

返回目录


如果本视频对您有所帮助,请点赞、关注、收藏!期待您的支持!

posted on   patton88  阅读(35)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
历史上的今天:
2022-02-17 设置Windows Server 2022、Win10、Win11自动登录的简单方法-OK
2021-02-17 百度地图的脑残设计,附上代码,为后来的码农们...

导航

< 2025年2月 >
26 27 28 29 30 31 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 1
2 3 4 5 6 7 8
点击右上角即可分享
微信分享提示