QT功能 实现动态内容国际化实验

news2025/2/23 23:55:19

文章目录

  • 1、新建项目
  • 2、给头文件添加代码
  • 3、给源文件添加代码
  • 4、生成ts文件
  • 5、翻译ts文件中的内容
  • 6、运行效果

1、新建项目

  随便新建一个默认项目即可,此步省略,如果新建项目都不会,就不应该来看这篇博文。

2、给头文件添加代码

  相关代码如下所示:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QComboBox>// 下拉框,选择需要切换的语言
#include <QLabel>   // 标签,显示对应的内容
#include <QPushButton>// 切换标签的内容
#include <QTranslator>// 翻译功能
#include <QFont> // 调节控件字体大小
#include <QMessageBox> // 提示用户选择了不存在的语言

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;

    // 两个标签,一个不设置翻译功能,另一个设置翻译功能
    QLabel *label, *label_tr;
    QPushButton *button;// 切换标签上的内容使用
    QComboBox *comboBox;// 选择语言
    QTranslator tran;// 翻译器,更改需要的时候,需要用上它

private slots:
    void on_button_clicked(void); // 按钮点击事件的槽函数(更改标签内容)
    void on_comboBox_activated(void); // 下拉框选中项改变事件的槽函数(选择语言)
    void changeEvent(QEvent *e);// 更改语言后会产生事件,在这个槽函数中处理跟界面语言相关内容(更新界面)

private:
    int current_index; // 静态数组的索引(取出某个位置的内容使用)
};
#endif // MAINWINDOW_H

在这里插入图片描述

3、给源文件添加代码

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>

// 新建一个静态数组,用来标记需要翻译的文本
static const char *strArr[] = {
    QT_TRANSLATE_NOOP("content1", "对比文本1"),
    QT_TRANSLATE_NOOP("content1", "对比文本2"),
    QT_TRANSLATE_NOOP("content1", "对比文本3")
};

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // 初始化界面中的所有控件
    label = new QLabel(this);
    label_tr = new QLabel(this);
    button = new QPushButton(this);
    comboBox = new QComboBox(this);

    // 给控件添加显示文本
    label->setText(QString(strArr[0]));
    label_tr->setText(QString(strArr[0]));
    button->setText(QString("切换内容"));
    comboBox->addItem(QString("中文"));
    comboBox->addItem(QString("English"));
    comboBox->addItem(QString("-"));

    // 调节控件大小和位置
    label->setGeometry(QRect(300, 20, 150, 30));
    label_tr->setGeometry(QRect(300, 70, 150, 30));
    button->setGeometry(QRect(200, 150, 120, 40));
    comboBox->setGeometry(QRect(380, 150, 120, 40));

    // 设置字体属性,此处字体大小为20个像素点
    QFont f;
    f.setPixelSize(20);

    // 对各个控件的设置字体属性
    label->setFont(f);
    label_tr->setFont(f);
    button->setFont(f);
    comboBox->setFont(f);

    // 静态数组当前索引位置为【0】,这意味着会选中数组的【第一个】元素
    current_index = 0;

    // 连接按钮的槽函数,当点击按钮时会发出信号,而后切换标签上的内容。QT5的写法
    connect(button, &QPushButton::clicked, this, &MainWindow::on_button_clicked);

    // 连接下拉框槽函数,实现语切换功能。QT4的写法
    connect(comboBox, SIGNAL(activated(int)), this, SLOT(on_comboBox_activated()));
}

MainWindow::~MainWindow()
{
    delete ui;
    delete label;
    delete label_tr;
    delete button;
    delete comboBox;
}

/**
 * @brief MainWindow::on_button_clicked
 * 槽函数,响应QPushButton的clicked信号。
 * 当用户点击按钮时,循环切换标签上显示的内容。
 */
void MainWindow::on_button_clicked(void)
{
    // 更新current_index以循环遍历字符串数组strArr
    // 使用模运算,确保索引在有效范围内(0到2)
    current_index = (++current_index) % 3;

    // 从静态数组strArr中取出当前索引对应的原文本
    // 并将其设置为label的显示文本
    label->setText(QString(strArr[current_index]));

    // 使用QCoreApplication::translate获取当前文本的翻译
    // 其中"content1"是翻译上下文,strArr[current_index]是待翻译的原文本
    // 将翻译后的文本设置为label_tr的显示文本
    label_tr->setText(QCoreApplication::translate("content1", strArr[current_index]));
}

/**
 * @brief on_comboBox_activated 槽函数,
 * 响应QComboBox的activated信号。
 * 当用户从comboBox控件中选择一个新项时,执行语言切换逻辑。
 */
void MainWindow::on_comboBox_activated(void)
{
    // 检查是否选择了中文或英文
    if(comboBox->currentIndex() == 0)
    {
        tran.load("://zh_CN.qm"); // 加载中文翻译文件,路径要换成qm文件所在路径,下面再说
    }
    else if(comboBox->currentIndex() == 1)
    {
        tran.load("://en_US.qm"); // 加载英文翻译文件,路径要换成qm文件所在路径,下面再说
    }
    else
    {
        // 如果用户没有选择预定义的语言项,显示警告并返回
        QMessageBox::warning(this, "警告", "必须选择一种语言!");
        return;
    }

    // 安装翻译器到qApp(当前应用),使翻译生效
    qApp->installTranslator(&tran);
}

/**
 * @brief MainWindow::changeEvent
 * 处理MainWindow的事件变化。
 * 当系统发送event事件时,如语言改变,该槽函数会被调用。
 * 事实上,调用 installTranslator 后,
 * 系统会给窗体发送信号将产生了 changeEvent 槽产生 event 事件
 * @param e 事件对象
 */
void MainWindow::changeEvent(QEvent *e)
{
    switch (e->type())
    {
        case QEvent::LanguageChange:
        {
            // 当语言改变事件被触发时,重新翻译Qt Designer生成的UI界面
            ui->retranslateUi(this);

            // 重新设置自定义控件label_tr的文本,以反映新的翻译
            // 使用QCoreApplication::translate获取当前文本的翻译
            label_tr->setText(QCoreApplication::translate("content1", strArr[current_index]));
            break;
        }
        default:
        {
            // 对于其他类型的事件,调用QWidget的changeEvent进行默认处理
            break;
        }
    }

    // 调用基类QWidget的changeEvent处理事件
    QMainWindow::changeEvent(e);
}

  由于添加的代码比较多,这部分就简单的截一下图,不截全了。

在这里插入图片描述

4、生成ts文件

  简单解释接下来需要用到的ts文件和qm文件:

   .ts 文件是翻译工作的源文件,用于开发阶段,而 .qm 文件是编译后的文件,用于应用程序的部署和运行时。
   .ts 文件是XML格式的,体积较大,可以包含除了文本之外的额外信息,如上下文信息和注释。
   .qm 文件是二进制格式,体积较小,包含了编译后的翻译数据,用于运行时加载和使用。
   开发者通常会在版本控制系统中跟踪 .ts 文件的更改,而 .qm 文件则在翻译完成后生成,并且只有在翻译更新时才会重新生成。

那么如何生成.ts文件呢?如下图所示:
在这里插入图片描述
  图中代码:

TRANSLATIONS = zh_CN.ts en_US.ts

  然后生成ts翻译文件:
在这里插入图片描述
在这里插入图片描述

5、翻译ts文件中的内容

  首先需要打开QT语言家,一般来说都会随着QT安装时把这个安装上:
在这里插入图片描述
  直接打开QT语言家是没有内容的,需要找到刚刚生成的ts文件,一般来说,如果创建一个项目时用的全是默认选项,那么生产的ts文件就在源代码项目文件夹下, 也就是“untitled”路径下,但我给项目起了“main”名,所以看见的ts文件是在“main”下:

在这里插入图片描述
  可以看到图中的弹出的对话框,注意别看错了!

在这里插入图片描述

在这里插入图片描述
  打开ts文件后看到的界面如下:

在这里插入图片描述
在这里插入图片描述
  当翻译完毕所有文本时,前面会出现“?”标记,这表示翻译了,但是翻译者没确认此项翻译是否通过,单击问号变成绿色的“√”即可:
在这里插入图片描述
在这里插入图片描述
  记得全部保存一下:
在这里插入图片描述
  保存完毕后需要发布一下qm文件,选择【全部发布】即可,如此操作会在项目文件夹下生成qm文件,但也可以选择【发布为……】,那么这样可以指定qm文件生成在哪个文件夹下,为了简单省事儿,此处我选择【全部发布】:

在这里插入图片描述
回到QT Creator,新建一个资源管理文件夹:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
  完成之后会看见这样的界面:
在这里插入图片描述
  选择文件,添加文件后记得需要保存一下,记得需要保存一下,记得需要保存一下:
在这里插入图片描述
在这里插入图片描述
  在上述代码中,“3、给源文件添加代码”有这么一部分:

// 检查是否选择了中文或英文
 if(comboBox->currentIndex() == 0)
 {
     tran.load("://zh_CN.qm"); // 加载中文翻译文件,路径要换成qm文件所在路径,下面再说
 }
 else if(comboBox->currentIndex() == 1)
 {
     tran.load("://en_US.qm"); // 加载英文翻译文件,路径要换成qm文件所在路径,下面再说
 }

事实上,需要在这里获得qm文件的路径:

在这里插入图片描述
  以我这里为例,en_US.qm 的文件路径为:://en_US.qm;zh_CN.qm文件路径为:://zh_CN.qm
  所以tran.load(对应qm文件路径);

6、运行效果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1654627.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何切换PHP版本

如果服务器上安装了多个php&#xff0c;可能会导致默认的php版本错误&#xff0c;无法启动swoole等服务&#xff0c; 查看命令行的php版本方法&#xff1a;https://q.crmeb.com/thread/9921 解决方法如下&#xff0c;选一个即可&#xff1a; 一、切换命令行php版本&#xff…

redis--安装

简介 官网&#xff1a;RedisInsight - The Best Redis GUI 各个版本官网下载地址&#xff1a;http://download.redis.io/releases/ Redis和Memcached是非关系型数据库也称为NoSQL数据库&#xff0c;MySQL、Mariadb、SQL Server、PostgreSQL Oracle 数据库属于关系型数据 应用…

DeepSeek API文档:创建对话补全的指南

DeepSeek平台不仅提供了一个用户友好的聊天界面&#xff0c;还为开发者提供了强大的API接口&#xff0c;使他们能够创建和集成智能对话补全功能。以下是关于如何使用DeepSeek API创建对话补全的详细介绍。 DeepSeek API概述 DeepSeek的API允许开发者通过编程方式与DeepSeek的…

单位档案寄存该怎么处理才好

处理单位档案寄存的方式可以根据实际情况来确定&#xff0c;以下是一些常见的处理方式&#xff1a; 1. 数字化存档&#xff1a;将单位档案进行数字化处理&#xff0c;通过扫描或拍照将文件转化为电子格式。这样可以方便查找和管理&#xff0c;减少纸质文件的存储量&#xff0c;…

Hikyuu-PF-银行股轮动交易策略实现

今天&#xff0c;带来的是“如何使用 Hikyuu 中的投资组合来实现银行股轮动交易策略”。 这个策略的逻辑很简单&#xff1a;持续持有两支市净率最低银行股&#xff0c;然后每月换仓 定义回测周期与回测标的 同样&#xff0c;首先定义回测周期&#xff1a; # 定义回测日期 …

Crowd counting 系列NO.2—MCNN

声明&#xff1a;博客是用latex写的&#xff0c;所以直接用图片来展示吧&#xff0c;效果是一样的。下载资源网上都很容易搜到&#xff0c;如需下载资源&#xff0c;请留言。

作为新型锂离子电池正极材料 磷酸锰铁锂(LMFP)行业发展空间有望扩展

作为新型锂离子电池正极材料 磷酸锰铁锂&#xff08;LMFP&#xff09;行业发展空间有望扩展 磷酸锰铁锂&#xff08;LMFP&#xff09;指在磷酸铁锂基础上添加锰元素而制成的新型磷酸盐类锂离子电池正极材料。磷酸锰铁锂含有橄榄石型结构&#xff0c;生产成本低、能量密度高、绿…

新版Idea配置仓库教程

这里模拟的是自己搭建的本地仓库环境&#xff0c;基于虚拟机搭建利用gogs创建的仓库 1、Git环境 你需要准备好git和仓库可以使用github 、gitee等 1.1 拉取代码 本项目使用 Git 进行版本控制&#xff0c;在 gogs 上创建一个个人使用的 git 仓库&#xff1a; http://192.168.…

自己动手写个 IDEA 高效插件:Swagger注解、JavaDoc一键生成

下面是一个普通的Request类&#xff0c;先简单的看一下&#xff1a; /*** TestRequest desc*/ Data Slf4j public class TestRequest {private String name;private Integer age;private Address address;/*** address desc*/SetterGetterpublic static class Address {privat…

Qt扫盲-Qt D-Bus概述

Qt D-Bus概述 一、概述二、总线三、相关概念1. 消息2. 服务名称3. 对象的路径4. 接口5. 备忘单 四、调试五、使用Qt D-Bus 适配器1. 在 D-Bus 适配器中声明槽函数1. 异步槽2. 只输入槽3. 输入输出槽4. 自动回复5. 延迟回复 一、概述 D-Bus是一种进程间通信(IPC)和远程过程调用…

第29章-SR技术概述

1. SR技术的产生背景 2. SR技术的基本概念 3. SR技术的基本原理 1. SR技术的产生背景 1.1 传统的路由器设备因其转发性能较低 ① 最长匹配算法的缺点&#xff0c;需要遍历整个路由表&#xff1b; ② 早期路由器多采用通用CPU进行转发处理&#xff0c;性能有限&#xff1b; ③…

第七届机电、机器人与自动化国际会议(ICMRA 2024)即将召开!

第七届机电、机器人与自动化国际会议&#xff08;ICMRA 2024&#xff09;将于2024年9月20日-22日在中国武汉举行。ICMRA 2024为各国专家学者提供一个学术交流的平台&#xff0c;讨论机电、机器人和自动化领域的最新研究成果和未来的研究方向&#xff0c;旨在能够建立起国家间&a…

(五)JSP教程——response对象

response对象主要用于动态响应客户端请求&#xff08;request&#xff09;&#xff0c;然后将JSP处理后的结果返回给客户端浏览器。JSP容器根据客户端的请求建立一个默认的response对象&#xff0c;然后使用response对象动态地创建Web页面、改变HTTP标头、返回服务器端地状态码…

【Redis7】了解Redis

1.常见数据库 1.1.键值存储数据库 如 Map 一样的key-value 对&#xff0c;典型代表就是 Redis。 1.2.列存储数据库 关系型数据库是典型的行存储数据库&#xff0c;按行存储的数据在物理层面占用的是连续存储空间&#xff0c;不适合海量数据存储。而按列存储则可实现分布式存储&…

新火种AI|马斯克聘用OpenAI泄密者,他们的梁子着实越结越深...

作者&#xff1a;小岩 编辑&#xff1a;彩云 就在最近&#xff0c;昔日就职于OpenAI的工程师Pavel Izmailov正式加入了马斯克的AI团队&#xff0c;他还在自己的推特上大张旗鼓的做着宣传&#xff1a;研究院xai。 AI工程师的跳槽本不值得惊讶&#xff0c;但Pavel的跳槽却在行…

什么牌子的洗地机质量最好?四款耐用高分产品推荐

洗地机具备了吸尘、擦拭、除菌等多种功能&#xff0c;可以一次完成多种清洁任务&#xff0c;帮助用户更高效地保持家居整洁&#xff0c;节省时间和精力&#xff0c;备受人们的喜爱。但是怎么挑选到优质的洗地机一直是大家关注的问题。今天&#xff0c;笔者将结合自己在家电行业…

mac通过termius连接Linux服务器

mac上安装 linux系统 如果有 linux服务器账号密码&#xff0c;那么上一步可忽略&#xff1b; 比如&#xff1a;直接连接阿里云或腾讯云账号 1. 安装termius 链接: https://pan.baidu.com/s/1iYsZPZThPizxqtkLPT89-Q?pwdbw6j 提取码: bw6j 官网 Termius - SSH platform for …

Linux-信号保存

1. 概念 进程执行信号的处理动作&#xff0c;称为 信号递达&#xff08;Delivery&#xff09; 信号从产生到递达之间的状态&#xff0c;称为 信号未决&#xff08;Pending&#xff09; 进程可以选择 阻塞&#xff08;Block&#xff09;某个信号 过程&#xff1a; 信号产生 ——…

flowable一对并发网关跳转的分析

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 http://218.75.87.38:9666/ 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a; h…

hadoop学习---基于Hive的聊天数据分析报表可视化案例

背景介绍&#xff1a; 聊天平台每天都会有大量的用户在线&#xff0c;会出现大量的聊天数据&#xff0c;通过对聊天数据的统计分析&#xff0c;可以更好的对用户构建精准的用户画像&#xff0c;为用户提供更好的服务以及实现高ROI的平台运营推广&#xff0c;给公司的发展决策提…