简介

Qt Linguist 提供了一套加速应用程序翻译和国际化的工具。Qt 使用单一的源码树和单一的应用程序二进制包就可同时支持多个语言和书写系统。

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

// 国际化翻译
QString language = "CH"; // 默认为中文,后期可以使用ini方式保存语言选项
QTranslator translator;
translator.load(QString(":/Translate_") + language);
a.installTranslator(&translator);

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

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

  • 提供用户可以用来切换语言的一种方法。

  • 对于每一个窗口部件或者对话框,重写 changeEvent 事件,当事件类型为QEvent::LanguageChange时,翻译文本进行重新调用(为了简单我把它放在一个单独的函数translateUI()中)。

多语言切换实例效果

添加翻译源

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

在pro中添加:

TRANSLATIONS += Translate_EN.ts \
Translate_CH.ts

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

翻译

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

发布翻译

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

源码分析

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

main.cpp:

#include "Translate.h"

#include <QApplication>

int main(int argc, char *argv[])
{
QApplication a(argc, argv); // 国际化翻译
QString language = "CH"; // 默认为中文,后期可以使用ini方式保存语言选项
QTranslator translator;
translator.load(QString(":/Translate_") + language);
a.installTranslator(&translator); Translate w;
w.setTranslator(&translator);
w.show(); return a.exec();
}

Translate.h:

#ifndef TRANSLATE_H
#define TRANSLATE_H #include <QWidget>
#include <QTranslator>
#include <QLabel>
#include <QComboBox>
#include <QVBoxLayout>
#include <QEvent>
#include <QApplication>
#include <QDebug> class Translate : public QWidget
{
Q_OBJECT public:
Translate(QWidget *parent = nullptr);
void setTranslator(QTranslator* translator); // 设置翻译对象 protected:
void changeEvent(QEvent *event); // 改变事件 private:
void translateUI(); // 统一设置需要被翻译的文本 QLabel *m_pLabText;
QComboBox *m_pComboBox;
QTranslator *m_translator; // 国际化翻译对象
};
#endif // TRANSLATE_H

Translate.cpp

#include "Translate.h"

Translate::Translate(QWidget *parent)
: QWidget(parent)
{
// 初始化界面
this->setFixedSize(400, 200); // 初始化控件
m_pLabText = new QLabel;
m_pComboBox = new QComboBox;
m_pComboBox->addItem("Chinese");
m_pComboBox->addItem("English"); // 主布局
QVBoxLayout *m_pLayoutMain = new QVBoxLayout(this);
m_pLayoutMain->addStretch();
m_pLayoutMain->addWidget(m_pLabText, 0, Qt::AlignCenter);
m_pLayoutMain->addSpacing(20);
m_pLayoutMain->addWidget(m_pComboBox, 0, Qt::AlignCenter);
m_pLayoutMain->addStretch();
m_pLayoutMain->setMargin(0); // 连接信号槽
connect(m_pComboBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), [=](int index) {
QString language_qm;
if(index == 0)
language_qm = QString(":/Translate_CH.qm");
else
language_qm = QString(":/Translate_EN.qm"); m_translator->load(language_qm);
qApp->installTranslator(m_translator); // 安装翻译器
}); // 统一设置需要被翻译的文本
translateUI();
} // 设置翻译对象
void Translate::setTranslator(QTranslator* translator)
{
m_translator = translator;
} // 改变事件:调用installTranslator后,系统会给窗体发送信号触发changeEvent事件
void Translate::changeEvent(QEvent *event)
{
switch (event->type())
{
case QEvent::LanguageChange:
translateUI();
break;
default:
QWidget::changeEvent(event);
}
} // 统一设置需要被翻译的文本
void Translate::translateUI()
{
m_pLabText->setText(tr("这是需要测试的文本"));
}

FloatWidget.cpp

#include "HelperWidget.h"

HelperWidget::HelperWidget(QWidget *parent) : QWidget(parent)
{
/* 界面初始化 */
this->setFixedSize(500, 200);
this->setWindowFlags(Qt::FramelessWindowHint);
this->setObjectName("FloatWidget");
setAttribute(Qt::WA_StyledBackground); // 不继承父窗口样式 m_pLabName = new QLabel;
m_pLabIp = new QLabel;
m_pBtnGet = new QPushButton;
m_pBtnPush = new QPushButton;
m_pBtnVideo = new QPushButton;
m_pLabSet = new QLabel;
m_pLabName->setText(tr("运维平台主屏"));
m_pLabIp->setText("192.168.1.71");
m_pBtnGet->setText("接管");
m_pBtnPush->setText("推送");
m_pBtnVideo->setText("视频");
m_pLabSet->setText("设置");
m_pLabSet->installEventFilter(this); // 悬浮小窗口-窗口部件初始化
m_pWidgetFloatSet = new QWidget;
m_pBtnUser = new QPushButton;
m_pBtnMatrix = new QPushButton;
m_pBtnShortCut = new QPushButton;
m_pWidgetFloatSet->setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
m_pWidgetFloatSet->installEventFilter(this);
m_pBtnUser->setText("用户权限");
m_pBtnMatrix->setText("矩阵");
m_pBtnShortCut->setText("快捷键");
QVBoxLayout *pVLayoutSet = new QVBoxLayout(m_pWidgetFloatSet);
pVLayoutSet->addWidget(m_pBtnUser);
pVLayoutSet->addWidget(m_pBtnMatrix);
pVLayoutSet->addWidget(m_pBtnShortCut); QHBoxLayout *pHLayoutBtn = new QHBoxLayout;
pHLayoutBtn->addWidget(m_pBtnGet);
pHLayoutBtn->addWidget(m_pBtnPush);
pHLayoutBtn->addWidget(m_pBtnVideo);
pHLayoutBtn->addWidget(m_pLabSet); QVBoxLayout *pVLayoutMain = new QVBoxLayout(this);
pVLayoutMain->addWidget(m_pLabName);
pVLayoutMain->addWidget(m_pLabIp);
pVLayoutMain->addLayout(pHLayoutBtn);
pVLayoutMain->addSpacing(60); // 信号槽链接
connect(m_pBtnGet, &QPushButton::clicked, [=]() {
emit sigBtnClickedGet();
});
connect(m_pBtnPush, &QPushButton::clicked, [=]() {
emit sigBtnClickedPush();
});
connect(m_pBtnVideo, &QPushButton::clicked, [=]() {
emit sigBtnClickedVideo();
}); // 在eventFilter中处理显隐则导致鼠标进入不了悬浮窗就会隐藏,所以用定时器去做
m_pTimerFloat = new QTimer;
m_pTimerFloat->setInterval(100);
connect(m_pTimerFloat, &QTimer::timeout, [=]() {
if ((m_pWidgetFloatSet != nullptr) && (m_pWidgetFloatSet->isVisible()))
{
// 判断鼠标是否游离到了悬浮窗之外,如果游离出去了,那么隐藏窗口
QPoint currentPos = QCursor::pos();
QRect floatWidgetRect = m_pWidgetFloatSet->rect();
QRect rect(m_pWidgetFloatSet->pos().x(), m_pWidgetFloatSet->pos().y(), floatWidgetRect.width(), floatWidgetRect.height());
if (!rect.contains(currentPos)){
m_pWidgetFloatSet->hide();
m_pTimerFloat->stop();
}
}
});
} // 事件过滤器(实现悬浮小窗口)
bool HelperWidget::eventFilter(QObject *obj, QEvent *event)
{
if (obj == m_pLabSet)
{
if (event->type() == QEvent::Enter)
{
QPoint oWidgetPoint = this->mapToGlobal(m_pLabSet->pos());
m_pWidgetFloatSet->setGeometry(oWidgetPoint.x(), oWidgetPoint.y() + m_pLabSet->height(), 80, 80);
m_pWidgetFloatSet->show(); m_pTimerFloat->stop();
return true;
}
else if (event->type() == QEvent::Leave) //如果是其他事件,可以进行进一步的处理
{
m_pTimerFloat->start();
return false;
}
else
return false;
}
else if (obj == m_pWidgetFloatSet)
{
if (event->type() == QEvent::Leave)
{
m_pWidgetFloatSet->hide();
return false;
}
else
return false;
}
else
return QWidget::eventFilter(obj, event);
}

Qt 国际化翻译的更多相关文章

  1. QT国际化 一 (lupdate/linguits/lrelease)

    QT国际化(lupdate/linguits/lrelease) 本文由乌合之众瞎写http://www.cnblogs.com/oloroso/ qt国际化其实就是qt中字符串的字符集编码的设置.当 ...

  2. 【Qt】Qt国际化【转】

    简介 Qt国际化属于Qt高级中的一部分,本想着放到后面来说,上节刚好介绍了Qt Linguist,趁热打铁就一起了解下. 对于绝大多数的应用程序,在刚启动时,需要加载默认的语言(或最后一次设置的语言) ...

  3. Qt国际化详细介绍,中文乱码以及解决方案

    Qt国际化的一般步骤 运行 lupdate,从应用程序的代码中提取所有界面上的可见字符.        这些可见字符必须被 tr() .QCoreApplication::translate().Qt ...

  4. QT国际化(中英转换)

    转载:https://blog.csdn.net/u012528526/article/details/54707233 QT国际化(中英转换) 我们都知道在安卓中,想做国际化很简单,只需要建立对应的 ...

  5. Ios国际化翻译工具

    IOS Translation Tool(IOS国际化翻译工具) 介绍 当IOS项目国际化的时候,手工去翻译每一个字符串是一件非常痛苦的事情.尤其是当项目中存在N多种语言.而且又很难保证,手工翻译的准 ...

  6. 给iview项目加一个i18n国际化翻译

    看了上一篇博客吗?我们就根据那一篇博客来,用里面的项目,进行我们接下来国际化翻译项目. 我们安装vue-i18n和js-cookie npm install vue-i18n npm install ...

  7. Qt国际化(Q_DECLARE_TR_FUNCTIONS() 宏给非Qt类添加翻译支持,以前没见过QTextEncoder和QTextDecoder和QLibraryInfo::location()和QEvent::LanguageChange)

    Internationalization with Qt 应用程序的国际化就是使得程序能在国际间可用而不仅仅是在本国可用的过程. Relevant Qt Classes andAPIs 以下的类支持Q ...

  8. qt 国际化(翻译时会触发changeEvent)

    1. 修改工程文件 .pro ,加入翻译源文件 hello_world.ts: TRANSLATIONS += \        Resource/translations/hello_world.t ...

  9. 6. QT国际化 translate QT语言家 翻译

    main. QTranslator *qtTranslator = new QTranslator(); if (IsChinese()) { qtTranslator->load(" ...

  10. 【Qt】Qt国际化(系统文本-QMessageBox按钮、QLineEdit右键菜单等)【转】

    简介 使用Qt的时候,经常会遇到英文问题,例如:QMessageBox中的按钮.QLineEdit.QSpinBox.QScrollBar中的右键菜单等.通常情况下,我们软件都不会是纯英文的,那么如何 ...

随机推荐

  1. js 字符串转换成数字(转)

    转换函数: js提供了parseInt()和parseFloat()两个转换函数.前者把值转换成整数,后者把值转换成浮点数.只有对String类型调用这些方法,这两个函数才能正确运行:对其他类型返回的 ...

  2. 在MVC3中修改KindEditor实现图片删除

    编辑器KindEditor可以上传图片,但却不能删除图片,因此我们通过修改一些文件,对KindEditor进行扩展,使得KindEditor能删除服务器上的图片. 主要方法就是:在图片空间中浏览图片, ...

  3. hibernate中的session缓存

    1.什么是session缓存? 在 Session 接口的实现中包含一系列的 Java 集合, 这些 Java 集合构成了 Session 缓存. 只要 Session 实例没有结束生命周期, 且没有 ...

  4. 【5】图解HTTP 笔记

    坚持.聪明.不畏困难,我将取得最后的胜利. 第一章 了解 Web 以网络基础 1. HTTP ( HyperText Transfer Protocol ): 超文本传输协议. 2. 通讯方式: 3. ...

  5. JavaScript原生的节点操作

    前言:原生是Javascript的基础,还是需要多多重视,时间长都忘记了,现在整理一下. 获取子节点 children 不是标准的dom属性,但是几乎被所有浏览器支持.不包含文本节点. 注意:在IE中 ...

  6. JavaScript-点击表格的表头进行排序

    HTML如下: <table class="heroinfo"> <thead title="点击排序"> <tr> < ...

  7. Docker for Windows(三)Docker镜像与容器的区别&常用命令

    Docker镜像(Image)是一堆只读文件(read-only layer),容器(container)的定义和镜像(image)几乎一模一样,也是一堆层的统一视角,唯一区别在于容器的最上面那一层是 ...

  8. IOC容器之Autofac

    讲到IOC容器,就必须提到DIP(依赖倒置原则). DIP是OOD(面向对象设计)的一个重要思想,在该原则上引申出了\IOC(控制反转)\DI(依赖注入)\IOC容器. 居然讲到IOC容器,当然我们要 ...

  9. “全栈2019”Java多线程第十章:Thread.State线程状态详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  10. 趣图:快下班了,剩一个bug,修复一下再走

      趣图:当我给老板展示我修复了那个 bug 时 趣图:当我以为这是最后一个Bug时……