您当前的位置: 首页 >  qt

龚建波

暂无认证

  • 2浏览

    0关注

    312博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Qt多语言翻译(国际化)

龚建波 发布时间:2021-12-18 17:58:14 ,浏览量:2

前言

有的软件需要根据用户的设置来切换显示的语言,Qt 提供了一套用于 Internationalization 的机制来帮助我们实现语言切换。

大致的流程:首先用 lupdate 工具根据源码中标记的字符串生成 ts 文件,然后通过 Linguist(Qt语言家)工具进行编辑,再用 lrelease 工具发布 qm 翻译文件,最后代码中加载这个 qm 翻译文件。其中 lupdate/lrelease 工具的使用已经集成到 Qt Creator 和 Linguist,可以快速地生成相应的文件。

操作流程

在 cpp 代码中使用 QObject::tr() 包含待翻译的文本,QML 代码中使用 qsTr() 包含待翻译的文本:

QObject::tr("第一项") //任意cpp文件使用
tr("第二项") //QObject子类函数中使用
qsTr("第三项")   //QML中使用

在 pro 中加上 TRANSLATIONS 设置,如 TRANSLATIONS += trans_zh_CN.ts,可以设置多个,每个对应生成的 ts 文件名:

TRANSLATIONS += trans_zh_CN.ts \
    trans_en_US.ts

并在 Qt Creator 中点击菜单栏-工具-外部-更新翻译,默认在 pro 目录生成对应的 ts 文件。下图为 Qt Creator 6.0 截图:

如果使用的 VS 开发,点击 Qt 插件菜单创建翻译文件。创建的文件会自动添加到目录,文件右键菜单有更新和发布的选项。下图为 Visual Studio 2019 截图:

使用 Qt 安装目录下的 Linguist 工具或者记事本打开 ts 文件进行编辑,设置对应的翻译文本,下面第一行是翻译后的文本,第二行是翻译的注释(tr 函数也可以加注释,填在第二个参数)。同时,可以看到每个文件的翻译是独立的,所以更新一个文件的文本后,只需要重新对该文件翻译即可。

所有需要翻译的文本都翻译完成后,点击 Qt Linguist 文件-保存,再点发布,默认会在 ts 同级目录生成 qm 文件,这就是我们发布程序时需要带上的翻译文件。(也可以在编辑保存后,在 Qt Creator 点更新翻译下面的发布翻译按钮)

有了 qm 文件后就是在程序中加载了,主要是借助 QTranslator 类,也可以使用多个 QTranslator 来加载多个不同的 qm 文件。

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QTranslator translator;
    translator.load("trans_zh_CN.qm");
    app.installTranslator(&translator);
    return app.exec();
}

要注意的是,如果加载翻译文件前,字符串已经赋值给变量,那是没法动态切换的,需要重新使用 tr 翻译的常量字符串赋值。

对于 QML,更新翻译后,需要调用 QQmlApplicationEngine 的 retranslate。更新的基本是 QML 中属性绑定的那些值,虽然 model-view 也会刷新,但如果字符串是保存在变量中的,那也没法被翻译了。对于那些没法动态切换的地方,可以通过全局的信号去重新加载数据。对于 QML 日历等组件,因为字符串是通过 QLocale 设置来生成的,所以切换翻译的时候需要重新设置 locale。

对于 QWidget,如果是 ui 文件中的文本,使用 ui->retranslateUi(this); 函数更新翻译,也可以参照该函数的实现,对其他的文本进行翻译:

    translator.load("trans_zh_CN.qm");
    qApp->installTranslator(&translator);
    ui->retranslateUi(this);

    //动态翻译
    label1->setText(QApplication::translate("MainWindow", "helllo", Q_NULLPTR));
    label2->setText(QApplication::translate("MainWindow", "qt", Q_NULLPTR));

其他,在 Qt5.15 版本,QTranslator 增加了 language() 函数。Qt Linguist 操作 ts 文件生成 qm 翻译文件后,是会携带 language 信息的,默认根据文件名中如 zh_CN 来区分,识别不了时会弹框让你自己选择,ts 就会保存这个语言信息,并带到 qm 文件中。QTranslator 读取 qm 文件后,如果有这个语言信息,就可以通过 QTranslator.language() 函数读取到,可以拿去设置 QLocale 等其他相关的。(如果是老版本 Qt 要使用到新的 qm 文件,并获取这个 language 属性,可以参照我下面的解析代码)

对于源文件中同一字符串需要不同翻译的情况,参照文档说明,可以在 tr() 函数中用第二个参数区分,第三个参数用于区分复数,详见文档

//通过tr第二第三个参数来消除歧义
QString Translator::getText(int i) const
{
    if(iinstallTranslator(&trans);
}

Translator::~Translator()
{
}

Translator *Translator::getInstance()
{
    static Translator instance;
    return &instance;
}

Translator::Language Translator::getLanguage() const
{
    return lang;
}

void Translator::setLanguage(Translator::Language type)
{
    if(type == lang || !langMap.contains(type))
        return;
    lang = type;
    //枚举名对应文件名,便于查找对应文件
    //但是对于可扩展的翻译,可以遍历目录下的文件,通过文件名来切换
    QString lang_str = langMap.value(type);
    QString trans_path = QString("%1/trans_%2.qm")
            .arg(qApp->applicationDirPath())
            .arg(lang_str);

    trans.load(trans_path);
    //qDebug()            
关注
打赏
1655829268
查看更多评论
0.0510s