简述: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")) {
- qApp->installTranslator(&translator);
- }
还可以使用别名:
- QTranslator translator;
- if (translator.load("en", ":/translations")) {
- qApp->installTranslator(&translator);
- }
![](https://img-blog.csdn.net/20170720161221100)
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函数,从而实现了语言的动态切换。
注意:加载主程序与子插件程序翻译文件时的别名或者路径不要相同,否则子插件程序翻译有可能不生效。
-
-
-
-
-
- void PlotViewerPlugin::changeEvent(QEvent* e)
- {
- QWidget::changeEvent(e);
- switch (e->type()) {
- case QEvent::LanguageChange:
- if(ui) ui->retranslateUi(this);
- break;
- default:
- break;
- }
- }
注意:需要更新翻译,便重复" C " ~ " D " 步骤
2、样例
![](https://img-blog.csdn.net/20170406161700462)
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);
- }
- }
转自:hebbely http://blog.csdn.net/hebbely/article/details/69388763 原创如有意见请回复,立即删除。