Qt 多国语言国际化

 

简述:Qt 提供了一种国际化方案,在程序使用过程中,不需要重启应用程序就可以实现语言的动态切换

 

1、实现语言国际化步骤 

 

要实现语言国际化,需要执行以下步骤:

 

 

A.  对用户可见的文本信息全部使用 tr()进行封装 

注意源码 utf-8 字符集;源码中需要翻译的字符串必须用英文,以防出现乱码

 

B.  创建语言文件 

 

 

 

打开 .pro文件,加入语言文件

 

TRANSLATIONS = $$PWD/i18n/Lidar_fr.ts \
        $$PWD/i18n/Lidar_en.ts \
        $$PWD/i18n/Lidar_ja.ts \
        $$PWD/i18n/Lidar_zh.ts

 

 

利用lupdate工具从源代码中扫描并提取需要翻译的字符串,生成 " .ts " 文件,即:

菜单栏 "工具"-> "外部" -> "Qt语言家" -> "更新翻译(lupdate)",将生成语言文件Lidar_fr.ts,Lidar_en.ts,Lidar_ja.ts,Lidar_zh.ts

或者,打开 Qt 5.7 for Desktop (MinGW 5.3.0 32bit) 命令行窗口,并进入 " .pro " 工程目录,执行命令:

lupdate  XXX.pro,便可生成 ".ts"翻译文件

 

C.编辑翻译语言文件 

 

 

利用 Linguist 工具 (Qt语言家) 来协助完成翻译工作。即启动Linguist 工具后,打开前面用 lupdate 生成的 " .ts "文件,对其中的字符串逐条进行翻译保存,主要是将源文对应的译文填写上。

另:由于 " .ts "文件用用了XML格式,所以也可以使用其他编辑器来打开 ".ts "文件并翻译

 

D.发布翻译文件

 

当翻译全部完成后,利用lrelease工具处理翻译好的 " .ts "文件,生成格式更为紧凑的 ".qm"文件,只有QTranslator能够正确识别它,即:

菜单栏 "工具"-> "外部" -> "Qt语言家" -> "发布翻译(lrelease)",便可生成对应的" .qm "文件。

 

E.  加载翻译文件

 

 

 
    QTranslator translator;
    if (translator.load("Lidar_en.qm", ":/translations")) { // 可以不带".qm"后缀名
        qApp->installTranslator(&translator);
    }

还可以使用别名

 

    QTranslator translator;
    if (translator.load("en", ":/translations")) { 
        qApp->installTranslator(&translator);
    }
 

 


 

F.  切换语言

 

method 1:

 

void MainWindow::Refresh()
{
    ui->listWidget->addItem(tr("item1"));
    ui->listWidget->addItem(tr("item2"));
    ui->listWidget->addItem(tr("item3"));
}


void MainWindow::actionEnglishToggled(bool state)
{
    if (state) {
        qApp->removeTranslator(&translator);
        if (translator.load("Lidar_en.qm", ":/translations")) {
            qApp->installTranslator(&translator);
            this->Refresh();
        }
    }
}

void MainWindow::actionFrancaisToggled(bool state)
{
    if (state) {
        qApp->removeTranslator(&translator);
        if (translator.load("Lidar_fr.qm", ":/translations")) {
            qApp->installTranslator(&translator);
            this->Refresh();
        }
    }
}

void MainWindow::actionJapaneseToggled(bool state)
{
    if (state) {
        qApp->removeTranslator(&translator);
        if (translator.load("Lidar_ja.qm", ":/translations")) {
            qApp->installTranslator(&translator);
            this->Refresh();
        }
    }
}


void MainWindow::actionChineseToggled(bool state)
{
    if (state) {
        qApp->removeTranslator(&translator);
        if (translator.load("Lidar_zh.qm", ":/translations")) {
            qApp->installTranslator(&translator);
            this->Refresh();
        }
    }
}

 

 

method 2:

 

当语言进行切换时,需要调用 ui->retranslateUi(this); 更新主窗口。 如果非主窗口,则这个 installTranslator 函数会触发void changeEvent(QEvent *e) 事件。原因如下:

系统调用完 installTranslator 函数之后,系统会自动给程序中所有的 QWidget 以及其子类发送 QEvent::LanguageChange()信号,并告知changeEvent槽event产生。所以,在要切换语言的每个窗体中都要重写接受QEvent::LanguageChange()信号的changeEvent函数,从而实现了语言的动态切换。

注意加载主程序子插件程序翻译文件时的别名或者路径不要相同,否则子插件程序翻译有可能不生效。

 

/*********************************************
 * changeEvent一般是当前widget状态改变后触发的
 * 如字体改变、语言改变之类的。
 * 该方法主要捕获改变事件,当语言改变后,执行相关操作。
********************************************/
void PlotViewerPlugin::changeEvent(QEvent* e) //重写的事件处理方法
{
    QWidget::changeEvent(e);   //让基类执行事件处理方法
    switch (e->type()) {
        case QEvent::LanguageChange:   //如果是语言改变事件
            if(ui) ui->retranslateUi(this); //更新UI的语言
            break;
        default:
            break;
    }
}

 

 

注意:需要更新翻译,便重复" C " ~ " D " 步骤

 

2、样例

 

LangSwitch.pro

 

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = LangSwitch
TEMPLATE = app


SOURCES += main.cpp\
        langswitch.cpp

HEADERS  += langswitch.h
TRANSLATIONS = lang_en.ts \
               lang_zh.ts \
               lang_la.ts

 

main.cpp

 

#include "langswitch.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    LangSwitch w;
    w.show();
    
    return a.exec();
}

 

langswitch.h

 

#ifndef LANGSWITCH_H
#define LANGSWITCH_H

#include <QWidget>
#include <QComboBox>
#include <QLabel>

class LangSwitch : public QWidget
{
    Q_OBJECT
    
public:
    LangSwitch(QWidget *parent = 0);
    ~LangSwitch();
private slots:
    void changeLang(int index);

private:
    void createScreen();
    void changeTr(const QString& langCode);
    void refreshLabel();

    QComboBox* combo;
    QLabel* label;
};

#endif // LANGSWITCH_H

 

langswitch.cpp

 

#include "langswitch.h"
#include <QVBoxLayout>
#include <QTranslator>
#include <QApplication>
#include <QDebug>

LangSwitch::LangSwitch(QWidget *parent)
    : QWidget(parent)
{
    createScreen();
}

LangSwitch::~LangSwitch()
{
    
}

void LangSwitch::createScreen()
{
    combo = new QComboBox;
    combo->addItem("English", "en");
    combo->addItem("Chinese", "zh");
    combo->addItem("Latin", "la");

    label = new QLabel;
    refreshLabel();

    QVBoxLayout* layout = new QVBoxLayout;
    layout->addWidget(combo, 1);
    layout->addWidget(label, 5);

    setLayout(layout);

    connect(combo, SIGNAL(currentIndexChanged(int)),this,SLOT(changeLang(int)));
    changeLang(0);
}

void LangSwitch::refreshLabel()
{
    label->setText(tr("TXT_HELLO_WORLD", "Hello World"));
}

void LangSwitch::changeLang(int index)
{
    QString langCode = combo->itemData(index).toString();
    changeTr(langCode);
    refreshLabel();
}

void LangSwitch::changeTr(const QString& langCode)
{
    static QTranslator* translator;

    if (translator != NULL)
    {
        qApp->removeTranslator(translator);
        delete translator;
        translator = NULL;
    }
    translator = new QTranslator;
    QString qmFilename = "lang_" + langCode;
    qDebug() << qmFilename;
    if (translator->load(QString("E:/.../LangSwitch/")+qmFilename))
    {
        qApp->installTranslator(translator);
    }
}

 

3、语言代码表

语言代码表

 

 

  • 5
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值