Qt之国际化

简介

Qt国际化属于Qt高级中的一部分,本想着放到后面来说,上节刚好介绍了Qt Linguist,趁热打铁就一起了解下。

对于绝大多数的应用程序,在刚启动时,需要加载默认的语言(或最后一次设置的语言)。在使用的过程中,我们也不需要重启应用程序而实现语言的动态切换。这样的话,易用性就非常好了。

  • 简介
  • 多语言切换
  • 源码分析
  • 添加翻译源
  • 翻译
  • 发布翻译
  • 加载翻译文件
  • 源码下载

多语言切换

要进行多语言的切换,需要执行以下步骤:

  1. 对用户可见的文本信息全部使用tr()进行封装
  2. 提供用户可以用来切换语言的一种方法。
  3. 对于每一个窗口部件或者对话框,重写changeEvent事件,当事件类型为QEvent::LanguageChange时,翻译文本进行重新调用(为了简单我把它放在一个单独的函数translateUI()中)。

源码分析

我们来看一个简单的示例:主界面、设置界面,设置界面可根据选择不同语言下拉选项实现语言的动态切换!

为了简单起见,这里只给出关键代码(源码下载请参考最下面下载地址):

设置界面:setting_dialog.h

typedef enum{
    UI_ZH,
    UI_EN
}LANGUAGE;

Q_DECLARE_METATYPE(LANGUAGE)

设置界面:setting_dialog.cpp

language_combo_box->addItem("chinese", QVariant::fromValue(UI_ZH));
language_combo_box->addItem("english", QVariant::fromValue(UI_EN));

qRegisterMetaType<LANGUAGE>("LANGUAGE");

connect(language_combo_box, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &SettingDialog::onIndexChanged);

void SettingDialog::changeEvent(QEvent *event)
{
    switch (event->type())
    {
    case QEvent::LanguageChange:
        translateUI();
        break;
    default:
        QDialog::changeEvent(event);
    }
}

void SettingDialog::translateUI()
{
    this->setWindowTitle(tr("setting dialog"));
    info_label->setText(tr("no brothers no programming"));
    language_label->setText(tr("language"));
    language_combo_box->setItemText(UI_ZH, tr("chinese"));
    language_combo_box->setItemText(UI_EN, tr("english"));
}

void SettingDialog::onIndexChanged()
{
    LANGUAGE language = language_combo_box->currentData().value<LANGUAGE>();

    emit switchLanguage(language);
}

主界面:MainWidget.cpp

connect(setting_dialog, &SettingDialog::switchLanguage, this, &MainWidget::switchLanguage);

void MainWidget::translateUI()
{
    this->setWindowTitle(tr("main widget"));
    welcome_label->setText(tr("welcome to Qt") + QString("26197884/26188347"));
    setting_button->setText(tr("setting"));
    ok_button->setText(tr("ok"));
    cancel_button->setText(tr("cancel"));
}

void MainWidget::setLanguage(LANGUAGE current_language)
{
    this->current_language = current_language;
}

void MainWidget::setTranslator(QTranslator* translator)
{
    this->translator = translator;
}

void MainWidget::changeEvent(QEvent *event)
{
    switch (event->type())
    {
    case QEvent::LanguageChange:
        translateUI();
        break;
    default:
        QWidget::changeEvent(event);
    }
}

void MainWidget::switchLanguage(LANGUAGE language)
{
    QString language_qm;
    switch(language)
    {
    case UI_ZH:
        language = UI_ZH;
        language_qm = QString(":/qm/main_widget_zh");
        break;

    case UI_EN:
        language = UI_EN;
        language_qm = QString(":/qm/main_widget_en");
        break;

    default:
        language = UI_ZH;
        language_qm = QString(":/qm/main_widget_zh");
    }

    if(current_language != language)
    {
        current_language = language;
        translator->load(language_qm);
        Util::writeInit(QString("./user.ini"), QString("language"), QString::number(language, 10));
    }
}

main.cpp

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QString language_value;
    QString language_suffix = QString("zh");
    LANGUAGE language = UI_ZH;
    bool is_read = Util::readInit(QString("./user.ini"), QString("language"), language_value);
    if(is_read)
    {
        language = (LANGUAGE)language_value.toInt();
        if(language == UI_EN)
        {
            language_suffix = QString("en");
        }
    }

    QTranslator translator;
    translator.load(QString(":/qm/main_widget_") + language_suffix);
    app.installTranslator(&translator); 

    MainWidget main_widget;
    main_widget.setTranslator(&translator);
    main_widget.setLanguage(language);
    main_widget.show();
    return app.exec();
}

流程:

  1. 进入main(),首先加载默认的语言(或最后一次设置的语言),然后显示主界面。
  2. 当打开设置界面后,首先加载当前选择的语言,然后通过下拉设置语言选项来进行语言切换(设置界面的switchLanguage信号关联到主界面的switchLanguage槽中),然后将当前的语言进行保存。

语言切换后,首先会进入changeEvent函数,判断当事件类型为QEvent::LanguageChange时,就会执行translateUI函数进行文本重新显示。

注:

  • Q_DECLARE_METATYPE:如果要使自定义类型或其他非QMetaType内置类型在QVariant中使用,必须使用该宏 。
  • qRegisterMetaType:如果非QMetaType内置类型要在信号与槽中使用。

添加翻译源

为了方便,这里只介绍中、英文之间的切换。

在pro中添加:

TRANSLATIONS += Resource/main_widget_zh.ts \
               Resource/main_widget_en.ts

选择:工具->外部->Qt语言家->更新翻译,则会生成对应的ts文件。

翻译

使用Qt Linguist打开要翻译的ts文件,对翻译源进行相应语言的翻译。

可参考:Qt Linguist介绍

发布翻译

选择:文件->发布,就会生成对应的qm文件。

加载翻译文件

使用QTranslator来加载生成的qm文件,就可以让程序显示指定的语言。

QTranslator translator;
translator.load(":/qm/main_widget_zh");
app.installTranslator(&translator); 

源码下载

时间: 2024-09-08 09:22:25

Qt之国际化的相关文章

Qt之国际化(系统文本-QMessageBox按钮、QLineEdit右键菜单等)

简介 使用Qt的时候,经常会遇到英文问题,例如:QMessageBox中的按钮.QLineEdit.QSpinBox.QScrollBar中的右键菜单等.通常情况下,我们软件都不会是纯英文的,那么如何处理这些问题呢?其实这也属于国际化的一部分. 下面,以中英文切换为例来为大家分享,其它语言切换类似. 简介 查找翻译文件 加载翻译文件 切换语言 查找翻译文件 qt_zh_CN.qm 见名知义,这正是处理中文的翻译文件. 我们可以从Qt的安装目录中找到它,以我的目录为例:D:\Qt\Qt5.5.1\

Qt学习之路(33):国际化(上)

2D绘图部分基本告一段落,还在想下面的部分要写什么,本来计划先说下view-model的相关问题,但是前面看到有朋友问关于国际化的问题,所以现在先来说说Qt的国际化吧! Qt中的国际化的方法有很多,常用的有使用QTextCodec类和使用tr()函数.前者将编码名称写到代码里面,除非你使用Unicode 编码,否则国际化依然是一个问题:后者就不会有这个问题,并且这也是Qt推荐的做法.因此,我们主要来说使用tr()函数的方法进行应用程序的国际化. 我们先来看一个很简单的MainWindow.为了清

《Qt 实战一二三》

简介 "我们来自Qt分享&&交流,我们来自Qt Quick分享&&交流",不管你是笑了,还是笑了,反正我们是认真的.我们就是要找寻一种Hold不住的状态,来开始每一天的点滴分享,我们是一个有激情,有态度的部队. 但是我们还是我们,我们只是多了一份责任.古语有云:"不积跬步无以至千里,不积小流无以成江海",所以每一个伟大事务的产生都不是一蹴而就的.现在我们要立足眼下,把第一站放在地球,"<Qt 实战一二三>&quo

Qt Linguist介绍

简介 Qt提供了一款优秀的支持Qt C++和Qt Quick应用程序的翻译工具.发布者.翻译者和开发者可以使用这款工具来完成他们的任务. 发布者:承担了全面发布应用程序的责任.通常,他们协调开发者和翻译者的工作,可以使用lupdate工具同步源代码,进行翻译,使用lrelease同步工具为发布应用程序创建运行时使用的翻译文件. 翻译者:可以使用Qt Linguist工具翻译应用程序的文本.当然,这必须要有专业的翻译知识. 开发者:必须创建Qt应用程序能够使用的翻译文本.也应该帮助翻译者识别短语出

QT 编码 字符集

http://dxwang.blog.51cto.com/384651/216271 [Qt 编码简单实验]         首先,Qt中得QString 类对字符串进行了封装,其内部使用Unicode对传入的串进行编码.这样一来,QString就可以处理绝大多数的国际语言.将QString中的字符根据语言翻译的过程,也就是Qt 的Translater针对程序中使用含有的tr("XXXXX"),进行翻译的过程.由于QString的Unicode编码,和本地系统的编码不一定是一致的(比如

基于QT的mplayer播放器

一.项目概述 Mplayer.它支持大量的多媒体文件格式,像常见的音频文件如mp3/wav/mid,常见的视频文件如avi/vcd/dvd/rm等等,各种视频编/解码方式也是应有尽有. 我们项目的目标是在liunx下,用QT做一个MPlayer皮肤,能够实现播放器的常见 功能,如:播放.停止.快进.快退.上/下一曲等.并把程序移植到ARM平台上. 二.功能体验 本节主要目的是让大家在学习具体实现过程前,先体验下播放器的功能. 1.PC端功能体验 将"项目代码/工程代码"目录下的mpla

Qt之界面数据存储与获取

简述 在GUI开发中,往往需要在界面中存储一些有用的数据,这些数据可以来自配置文件.注册表.数据库.或者是Server. 无论来自哪里,这些数据对于用户来说都是至关重要的,它们在交互过程中大部分都会被用到,例如:单击一个用户头像,显示该用户的详细信息(等级.昵称.姓名.个人说明). 简述 常见接口 数据源 setData和data 单独存储 整体存储 setItemData和itemData setUserData和userData 自定义数据 常见接口 Qt中,可以通过绝大部分已有的接口来存数

Qt学习之路(34):国际化(下)

上次说了国际化的过程,现在来看一下具体的国际化的相关代码. 在代码中,我们使用tr()将需要翻译的字符串标记出来.lupdate工具就是提取出tr()函数中的相关字符串.tr()函数是QObject类的一个static函数,其签名如下: static QString tr(const char *sourceText, const char *comment = 0, int n = -1); 虽然我们只传了一个参数,但是实际上tr()函数是接受3个参数的.第一个参数是我们需要翻译的文字,如果使

[Qt教程] 第46篇 进阶(六) 国际化

[Qt教程] 第46篇 进阶(六) 国际化 楼主  发表于 2013-10-7 09:23:45 | 查看: 109| 回复: 0 国际化 版权声明 该文章原创于Qter开源社区 导语 在第2篇中讲述如何显示中文时,曾提到使用QTextCodec和tr()的方式直接显示中文,其实这只是一种临时的方法,方便我们快速完成程序,显示效果.当真正要发布一个程序时,最好的方式是在程序中使用英文字符串,而后使用国际化工具进行翻译. 国际化的英文表述为Internationalization,通常简写为I18