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

文章目录

1、新建项目

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

2、给头文件添加代码

相关代码如下所示:

c++ 复制代码
#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、给源文件添加代码

c++ 复制代码
#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文件呢?如下图所示:

图中代码:

c++ 复制代码
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、给源文件添加代码"有这么一部分:

c++ 复制代码
// 检查是否选择了中文或英文
 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、运行效果

相关推荐
Thunter_24 分钟前
QT中常用英语单词
开发语言·qt
科学的发展-只不过是读大自然写的代码27 分钟前
qt播放视频
数据库·qt·音视频
激昂~逐流29 分钟前
Qt使用sqlite数据库及项目实战
数据库·qt·sqlite·学生信息管理系统
溪渣渣_梁世华30 分钟前
Qt 进程间通信(一)——QSharedMemory共享内存
c++·qt·进程间通信
师从名剑山32 分钟前
Qt实现检测软件是否多开
qt·软件需求
-凌凌漆-1 小时前
【Qt】QItemSelectionModel 添加选中行
qt
从后端到QT3 小时前
Qt 线程 QThread类详解
开发语言·qt
YoungMLet4 小时前
【QT】多元素控件
c语言·开发语言·c++·qt·ui
DS小龙哥7 小时前
QT+OpenCV在Android上实现人脸实时检测与目标检测
android·人工智能·qt·opencv·目标检测
小老鼠不吃猫8 小时前
力学笃行(四)Qt 线程与信号槽
c++·qt·信息可视化