QTranslator翻译器

本文详细介绍了如何在Qt环境中实现多语言支持,包括新建Qt工程,配置pro文件,使用qmake和lupdate/lrelease工具生成翻译文件,使用Qt Linguist进行翻译,以及在代码中通过QTranslator加载和切换不同语言。同时,文中还探讨了在main函数和Widget类中加载qm文件的区别,以及在ComboBox中切换语言时需要注意的界面刷新问题。
摘要由CSDN通过智能技术生成

目录

操作步骤 

 编写代码注意事项 

容易疑惑点

代码


操作步骤 

步骤:1.新建一个qt工程

           2.在该工程的pro文件中添加(什么名字在什么路径下不影响)

TRANSLATIONS = lang_en.ts\
lang_zh.ts\

           3.右键工程名,执行qmake。

                  第一种方法:工具---》外部---》qt语言家---》更新翻译,即可生成.ts文件(其实是个xml文件)。

                  第二种方法:在想要放ts文件的目录下,按住shift键,点击鼠标右键,选择在此处打开powershell窗口,执行“qt安装目录/bin/lupdate.exe   xxx.pro文件”。

                  两种方式都会生成ts文件。

           4.在qt安装目录的bin下打开qt linguist,或者在开始菜单中打开也行。点击文件---》打开---》把多个ts文件都选中打开。开始翻译。翻译结束ctrl+s保存。

                    第一种方法:再次点击文件----》发布全部。

                    第二种方法:在想要放qm文件的目录下,按住shift键,点击鼠标右键,选择在此处打

开powershell窗口,执行“qt安装目录/bin/lrelease.exe   xxx.pro文件”。

                   两种方式都会生成qm文件。

           5.点击qt左下角三角形运行即可。

 编写代码注意事项 

在main中写QTranslator代码 。         

 int main(int argc, char *argv[])
 {
    QApplication app(argc, argv);
    //翻译程序
    QTranslator translator;
    translator.load("cn.qm");
    app.installTranslator(&translator);
    app.exec();
}

但是在main中像上面方式载入qm文件在实际项目开发过程中没有意义。因为在main中只能加载一个qm文件。如果你的界面只需要一种语言,直接在widget中设置好相应的语言文本就可以了。

所以写到widget中是较为合适的。

在widget中添加QComBoBox,在QComBoBox中添加多种语言。

#include <QApplication>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    m_translator = new QTranslator();
    
}

关键代码1:
connect(ui->comboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(changeLang(int)));

关键代码2:
void changeLang(int)
{
    if(m_translator != nullptr)
    {
        qApp->removeTranslator(m_translator);
    }

    bool flag = m_translator->load(langCode);
    if(flag)
    {
        qDebug() << "load successful";        
        qApp->installTranslator(m_translator);
    }
    else
    {
        qDebug() << "load failed" ;
    }
}

当你按照上述方式加载文件后,如果文件路径正确,会打印load successful。 但是你切换combobox时,发现你想翻译的文件内容没有发生改变。在main中改变qm文件,widget却可以更改成相应的语言。

什么原因呢?因为改变QComBoxBox时,界面已经初始化了。改变QComBoxBox对应的qm文件之后,会查找带有“tr”的地方。但是这个槽执行到installTranslator就结束了。找不到tr文本。

所以需要在installTranslator之后加类似以下代码(凡是你需要翻译的都要像以下代码一样加上)

ui->label->setText(tr("Hello World"));
ui->label_2->setText(tr("we"));

comboBox->setItemText(0, tr("English"));
comboBox->setItemText(1, tr("Chinese"));

在查找资料的过程中,发现有人写以下代码。

ui.retranslateUi(this);

只有label,button之类的是可以这么写的,点击button切换像手机的中英文切换。但是用到combobox时,使用这个就不行了。retranslateUi是ui文件生成的ui_xxx.h中的接口。该接口会将combobox先清空,然后按照你在构造中添加item的顺序重新添加item。导致的问题就是你选择第二个item,界面上永远显示第一个ltem。

容易疑惑点

网上资料有说加载的qm文件必须放在你翻译的界面前面。这句话对了一半。

1.qm文件可以在翻译的界面前面加载,但不是必须的。

2.qm文件也可以在翻译的界面里面加载。但需要加入刷新界面的语句。比如:

ui->label->setText(tr("Hello World"));
ui->label_2->setText(tr("we"));

comboBox->setItemText(0, tr("English"));
comboBox->setItemText(1, tr("Chinese"));

代码

widget文件证明了疑惑点中的第二个

secondForm文件证明了疑惑点中的第一个。

ui文件自己根据代码搞吧。

pro文件部分

.....
TRANSLATIONS = lang_en.ts\
lang_zh.ts\
lang_la.ts
widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QComboBox>
#include <QTranslator>

#include "secondform.h"

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
private slots:
    void changeLang(int index);

private:
    void createScreenLocal();
    void changeTr(const QString& langCode);
    void refreshLabel();
private:
    Ui::Widget *ui;
    QComboBox* combo;
    static QTranslator * m_translator;
    secondForm* m_secFormFo;
};

#endif // WIDGET_H

 

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QApplication>

#include <QDebug>
#include <QVBoxLayout>


QTranslator * Widget::m_translator = nullptr;

//总共两个问题
//1.加载的qm文件必须放在你翻译的某个界面前面。
//2.假如你没放在前面,在本界面中载入,需要在载入文件之后加入刷新界面的语句。
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    m_translator = new QTranslator();
    createScreenLocal();
}

Widget::~Widget()
{
    delete ui;
}

void Widget::changeLang(int index)
{
    QString langCode = QString("D:/project/Qt/translator1/");
    if(index == 0)
    {
        langCode +="lang_en.qm";
    }
    else if(index == 1)
    {
        langCode +="lang_zh.qm";
    }
    else
    {
        langCode +="lang_la.qm";
    }
    changeTr(langCode);
    refreshLabel();

    m_secFormFo = new secondForm();
    m_secFormFo->show();
}

void Widget::createScreenLocal()
{
    combo = new QComboBox();
    combo->addItem(tr("English"));
    combo->addItem(tr("Chinese"));
    combo->addItem(tr("Latin"));
    QVBoxLayout*  layout = new QVBoxLayout();
    layout->addWidget(combo,1);
    refreshLabel();
    setLayout(layout);
    connect(combo,SIGNAL(currentIndexChanged(int)),this,SLOT(changeLang(int)));
}

void Widget::changeTr(const QString &langCode)
{
    if(m_translator != nullptr)
    {
        qApp->removeTranslator(m_translator);
    }

    bool flag = m_translator->load(langCode);
    if(flag)
    {
        qDebug() << "load successful";
        qDebug() << langCode;
        qApp->installTranslator(m_translator);
    }
    else
    {
        qDebug() << "load failed" ;
    }
}

void Widget::refreshLabel()
{
    ui->label->setText(tr("Hello World"));
    ui->label_2->setText(tr("we"));

    combo->setItemText(0, tr("English"));
    combo->setItemText(1, tr("Chinese"));
    combo->setItemText(2, tr("Latin"));
}
main.cpp

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

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

    Widget w;
    w.show();

    return a.exec();
}
secondForm.h

#ifndef SECONDFORM_H
#define SECONDFORM_H

#include <QWidget>

namespace Ui {
class secondForm;
}

class secondForm : public QWidget
{
    Q_OBJECT

public:
    explicit secondForm(QWidget *parent = 0);
    ~secondForm();

private:
    Ui::secondForm *ui;
};

 

secondForm.cpp

#include "secondform.h"
#include "ui_secondform.h"

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

secondForm::~secondForm()
{
    delete ui;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值