【缘起】

最近找到一个看起来比较好用的开源工具( 然鹅不太会用 ),但整个界面都是英文的。

不过由于是 Qt 写的,所以就尝试自己做些汉化。

然后了解到不少实现多国语言相关的技术( 以及一些坑 (‾◡◝) )。

这里写一篇完整且具体的,「 如何在 Qt / Qml 中支持多国语言 & 动态翻译 」


【正文开始】

按例先上效果图。

  • QtWidgets 的:

文本及翻译如下:

- MainWindow Title 「 MainWindow  => "主窗口"」

- Menu Title「 Language => "语言"」

- Menu [ Action Text ] 「 English => "英文"  Chinese => "中文"」

- PushButton Text「 Change Language => "更改语言"」

- Label Text「 This is "Test Text" => "这是"测试文本""」

- StatusBar Message「 Language changed to English / Chinese => "语言变更为英文 / 中文"」

其中,MainWidnow & Menu & Action & Label 是在 QtDesigner 中添加的,而 PushButton 为手动编码( 手动添加 ),而 StartusBar 来自 QMainWindow 本身,在运行时更改其文本

来看看关键代码:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPushButton>
#include <QTranslator>MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);m_translator = new QTranslator(this);QCoreApplication::instance()->installTranslator(m_translator);m_changeBtn = new QPushButton(this);m_changeBtn->setText(tr("Change Language"));m_changeBtn->setGeometry(40, 100, 120, 40);connect(m_changeBtn, &QPushButton::clicked, this, [this]() {if (m_language == Language::English) {setLanguage(Language::Chinese);} else {setLanguage(Language::English);}});connect(ui->actionChinese, &QAction::triggered, this, [this]() {setLanguage(Language::Chinese);});connect(ui->actionEnglish, &QAction::triggered, this, [this]() {setLanguage(Language::English);});emit ui->actionEnglish->triggered();
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::setLanguage(MainWindow::Language lang)
{switch (lang) {case Language::Chinese:if (m_translator->load("./language/Translator_widget_zh_CN.qm")) {ui->actionChinese->setChecked(true);ui->actionEnglish->setChecked(false);m_language = Language::Chinese;statusBar()->showMessage(tr("--- Language changed to Chinese"), 1000);}break;case Language::English:m_translator->load("");ui->actionChinese->setChecked(false);ui->actionEnglish->setChecked(true);m_language = Language::English;statusBar()->showMessage(tr("--- Language changed to English"), 1000);break;}retranslateUi();
}void MainWindow::retranslateUi()
{ui->retranslateUi(this);m_changeBtn->setText(QCoreApplication::translate("MainWindow", "Change Language", nullptr));
}

要想在 Qt 中实现多语言动态翻译,大致分为几个步骤:

1、在 .pro 文件中加入 TRANSLATIONS += $${TARGET}_zh_CN.ts ( ts文件名可以任意,但建议如此,稍后解释原因,zh_CN 代表简体中文 )。

2、使用 tr() 函数将需要翻译的字符串包裹起来,tr() 可以来自 QMetaObject::tr ( 非static,需要Q_OBJECT宏 ),或者来自 QObject::tr ( static函数 ),被包裹字符串将会被提取到翻译文件( ts文件 )。

关于 *.ts *.qm 文件

*.ts 文件是从 Qt / C++ 或相关绑定 (如 Python 语言绑定 PyQt、PySide) 源代码中,提取出来的 "Translate Source 翻译资源" 文件

*.qm 文件是从 *.ts 文件,采用 Qt 自带的 lrelease.exe 并运行相关 CMD 命令或由 Qt 自带的 linguist.exe 应用生成的 "Qt Multi-language" 本地化文件。

关于 QMetaObject::tr() / QObject::tr() 函数

通过阅读源码,发现 tr() 函数的调用顺序为:

【 QMetaObject::tr() / QObject::tr() 】=> 【 QCoreApplication::translate() 】=> 【 QTranslator::translate() 】

最终的 QTranslator::translate() 则会对安装的 Translator ( 包含 qm 文件 ) 进行解析,然后返回相应语言的字符串。

3、使用 lupdate.exe 生成 / 更新 翻译文件( .ts )。

4、使用 linguist.exe ( Qt 语言家 ) 打开 ts 文件并进行翻译。

5、发布翻译文件( .qm ),使用 lrelease.exe。

6、在代码中安装并载入翻译文件:

    QCoreApplication::instance()->installTranslator(m_translator);...m_translator->load("./language/Translator_widget_zh_CN.qm")。

7、重新载入文本( 翻译后的文本 ):retranslateUi(),很重要,很多人不能动态翻译就是缺少这一步

retranslateUi() 即重新设置 setText / setTitle 等等,然后使用 QCoreApplication::translate() 获取翻译后的对应字符串。

OK!先告一段落,来说下步骤一中的原因:这是为了稍后可以更方便的进行翻译。

具体原因见上一篇:Qt Linguist(语言家)与QtCreator集成

  • QtWidgets 中很简单,那么 Qml 呢?

有些类似,但也有很多不同,来瞅瞅效果图 :

当然,这里用的 QtQuick Controls 2.13,在桌面平台看起来稍微有些大了,不过也不影响。

整个界面与 QtWidgets 一致,main.cpp 关键代码:

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QTranslator>#define q_invokalbe Q_INVOKABLEclass TranslateController : public QObject
{Q_OBJECTQ_ENUMS(Language)public:enum class Language{English = 1,Chinese};public:static TranslateController* instance(QQmlEngine *engine) {static TranslateController controller(engine);return &controller;}void retranslateUi() {m_engine->retranslate();}q_invokalbe void loadLanguage(Language lang) {switch (lang) {case Language::Chinese:if (m_translator->load("./language/Translator_qml_zh_CN.qm")) {emit message(tr("--- Language changed to Chinese"));}break;case Language::English:m_translator->load("");emit message(tr("--- Language changed to English"));break;}retranslateUi();}signals:void message(const QString &msg);private:TranslateController(QQmlEngine *engine) {m_engine = engine;m_translator = new QTranslator(this);QCoreApplication::installTranslator(m_translator);}QQmlEngine *m_engine = nullptr;QTranslator *m_translator = nullptr;
};int main(int argc, char *argv[])
{QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);QGuiApplication app(argc, argv);qmlRegisterUncreatableType<TranslateController>("an.translate", 1, 0, "Language", "不能创建TranslateController对象");QQmlApplicationEngine engine;auto translateController = TranslateController::instance(&engine);engine.rootContext()->setContextProperty("controller", translateController);const QUrl url(QStringLiteral("qrc:/main.qml"));QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,&app, [url](QObject *obj, const QUrl &objUrl) {if (!obj && url == objUrl)QCoreApplication::exit(-1);}, Qt::QueuedConnection);engine.load(url);return app.exec();
}#include "main.moc"

其中,关键点为 QQmlEngine::retranslate() 函数,此函数刷新所有使用标记为翻译( qsTr() )的字符串的绑定表达式,注意此函数在 Qt 5.10 以后可用

main.qml代码如下:

import QtQuick 2.13
import QtQuick.Window 2.13
import QtQuick.Controls 2.13
import an.translate 1.0ApplicationWindow {id: rootvisible: truewidth: 640height: 480title: qsTr("MainWindow")property int language: Language.EnglishActionGroup {id: languageGroup}menuBar: MenuBar {Menu {id: languageMenutitle: qsTr("Language")Action {checked: language == Language.Englishcheckable: truetext: qsTr("English")ActionGroup.group: languageGrouponTriggered: {controller.loadLanguage(Language.English);language = Language.English;}}Action {checked: language == Language.Chinesecheckable: truetext: qsTr("Chinese")ActionGroup.group: languageGrouponTriggered: {controller.loadLanguage(Language.Chinese);language = Language.Chinese;}}}}Connections {target: controlleronMessage: {statusBar.text = msg;}}Text {id: statusBarvisible: falsecolor: "red"anchors {bottom: parent.bottombottomMargin: 30left: parent.leftleftMargin: 20}onTextChanged: {visible = true;textTimer.restart();}Timer {id: textTimerrunning: falseinterval: 1000onTriggered: statusBar.visible = false;}}Label {id: labelanchors.centerIn: parenttext: qsTr("This is \"Test Text\"")font { pointSize: 26 }}Button {id: buttontext: qsTr("Change Language")anchors {bottom: label.topbottomMargin: 30horizontalCenter: parent.horizontalCenter}onClicked: {if (language == Language.English){controller.loadLanguage(Language.Chinese);language = Language.Chinese;} else {controller.loadLanguage(Language.English);language = Language.English;}}}
}

实际上,与 Widgets 最大区别在于:qml 中翻译的字符串需要用 qsTr() / qsTranslate() 包裹起来。


【结语】

终于写完了。。为此我还专门写了两个版本的示例。

本篇文章应当是最全面具体的「 如何在 Qt / Qml 中支持多国语言 & 动态翻译 」

如果有其他问题 & 错误,欢迎留言 / 评论 / 私信。

最后,附上项目链接:

Github的:GitHub - mengps/QmlExamples: Qt Quick/Qml 示例,说不定有用呢~

CSDN的:Qt/Qml中支持多国语言_qt多语言,qml多语言-C++文档类资源-CSDN下载

Qt / Qml 中支持多国语言相关推荐

  1. qt支持的html5,用 Qt 5 中实现多国语言支持

    Qt5 实现多国语言 引言 目的:自用/笔记 时间:2018-02-13 01:13 平台: Windows 7 项目:将英语界面添加德语和土耳其语翻译 步骤 使用默认语言写出整个工程,这里使用英语作 ...

  2. c 程序多语言,怎样在程序中利用C支持多国语言

    怎样在程序中利用C支持多国语言 本文以emule为例,探讨一下多国语言支持的实现.选择emule,因为它的多国语言支持实现的相当好,可以支持动态切换.而且最关键,它是开源的,可以直接通过源码来研究它的 ...

  3. Android支持多国语言

    1.如何让App支持多国语言的设置? 为了让以后方便代码的管理维护,推荐将一些尺寸,文字等都使用@string/xxx的引用方式. 为了达到目的,我们先需要知道国际中的各国语言和地区语言的简称,如最下 ...

  4. OEA 中的多国语言实现

    本篇博客主要描述在 OEA 框架中的多国语言框架的原理及应用. 多国语言常见实现及原理分析 管理软件平台,一般来说,都应该支持多国语言,以支持应用程序走向国际化.OEA 最近也提供了多国语言框架,它可 ...

  5. oracle支持几国语言,Oracle数据库多语言支持

    二.使用Unicode在需要支持多国语言的环境里,使用Unicode可以轻松解决数据存储问题. Oracle中支持以下几种Unicode编码?AL32UTF8 使用1,2,3个字节进行编码,扩展字符集 ...

  6. 柔宇发布“手写神器”柔记樱雪白特别版,支持7国语言手写识别

    深圳2018年9月26日电 /美通社/ -- 9月23日,柔宇科技在2018北京国际设计周期间首次对外发布柔宇科技的"柔性+"办公教育类升级新品 -- 柔记 RoWrite S 智 ...

  7. Make uploadify button text support multiple languages(使uploadify的buttonText支持多国语言)

    uploadify 控件的按钮不支持多国语言,这里介绍如何修改后使其支持多国语言. 1.jquery.uploadify.v2.1.4.js文件 70行 原代码:if (settings.button ...

  8. 字符编码转换类(支持多国语言)

    头文件StrConvertor.h /* * 字符编码转换库,支持多国语言. */ #pragma once #include <string>class CStrConvertor { ...

  9. QT在QML下实现多国语言翻译

    在某些情况下,我们使用QT开发的界面需要完成多国语言的翻译工作.QT在这方面其实已经给出了支持,本文主要讲述在使用QML编写界面的情况下如何实现多国语言的翻译. 若要实现QT多国语言翻译,必须要搞清楚 ...

最新文章

  1. 学Java好不好 要避开哪些雷区
  2. 有微型计算机广告,广告还会受欢迎?都是斯巴达克显卡惹的“祸”
  3. 介绍Python的魔术方法 - Magic Method
  4. vue2使用$set()使对象新增属性后触发视图更新
  5. springboot start
  6. 易宝支付碰到 交易签名无效问题
  7. 关于flash网页播放中wmode和direct
  8. es6 class语法糖
  9. 3516a 自带的ive 算子的运行情况分析
  10. Swing-JTree树模型的操作
  11. flashfxp使用图文教程,flashfxp使用图文教程简单介绍
  12. MATLAB中findpeaks函数使用
  13. 螳螂捕蝉、黄雀在后——从一个成语谈观察家模式
  14. 【C语言】利用for循环来创建一个金字塔
  15. 502 Bad Gateway 怎么解决?
  16. java技术--电话语音通知
  17. 人是Web3最终进化
  18. 解决Android Studio(2022版)gradle下载慢问题
  19. right 微信小程序_js实现微信小程序左右滑动功能
  20. Unlabeled Samples Generated by GAN Improve the Person Re-identification Baseline in vitro 论文阅读

热门文章

  1. html双击回顶部,百度/微信小程序点击按钮回到顶部(scrollTop=0)/点击拨打电话...
  2. C语言提取gpgga例子
  3. 《深入理解Java虚拟机第3版》垃圾收集器与内存分配策略、虚拟机性能监控故障处理工具
  4. 【编译原理】Compiler_Stanford University 编译原理课程地址
  5. C/C++test白盒测试的落地实践
  6. google日历免费短信天气提醒
  7. j-link 驱动下载地址
  8. 2022年认证杯SPSSPRO杯数学建模B题唐宋诗的定量分析与比较研究程序
  9. Visio中添加MathType公式
  10. 为什么学微电子的都怕掉进材料的坑?