QT 软件中英文切换

时间:2021-03-18 20:15:29

本文内容学习自Johan Thelin的《Foundations of Qt Development》,欢迎交流。

本文中的例子是将软件版本在中英文之间动态切换,在书中归属语言国际化的章节Internationalization and Localization。在实现上用到了lupdate, linguist, lrelease等qt自带的工具,中间文件有翻译源文件ts文件,翻译后文件qm文件。

我们的工程是internal,文件有:

.
├── chinese.qm (由.pro生成后的翻译文件)
├── chinese.ts (由.pro生成后的翻译源文件)
├── english.qm (由.pro生成后的翻译文件)
├── english.ts (由.pro生成后的翻译源文件)
├── internal (生成后的可执行文件)
├── internal.pro
├── internal.pro.user
├── main.cpp
├── mainwindow.cpp
├── mainwindow.h
└── mainwindow.ui


QT 软件中英文切换
运行效果

ts文件的生成

在pro中加上:
TRANSLATIONS += english.ts chinese.ts
然后,使用lupdate生成xml文件(.ts文件).

[edemon@CentOS internal]$ lupdate internal.pro
Updating 'english.ts'...
Found 8 source text(s) (8 new and 0 already existing)
Updating 'chinese.ts'...
Found 8 source text(s) (8 new and 0 already existing)
[edemon@CentOS internal]$ ls
chinese.ts internal.pro main.cpp mainwindow.cpp mainwindow.ui ui_mainwindow.h
english.ts internal.pro.user main.o mainwindow.h Makefile

xml内容:

[edemon@CentOS internal]$ cat chinese.ts 
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.0">
<context>
<name>MainWindow</name>
<message>
<location filename="mainwindow.ui" line="14"/>
<source>MainWindow</source>
<translation type="unfinished"></translation>
</message>
...
</context>
</TS>

修改ts文件(翻译源文件)

可以直接编译ts文件,也可以使用工具linguist。
如下:
QT 软件中英文切换

修改的对应项将问号点成对勾,不然ts文件一直显示translation type=”unfinished”
如下:
QT 软件中英文切换

    <message>
<location filename="mainwindow.cpp" line="32"/>
<source>chinese</source>
<translation>中文</translation>
</message>
<message>
<location filename="mainwindow.cpp" line="33"/>
<source>Mainwindow</source>
<translation type="unfinished">主窗体</translation>
</message>

english.ts被linguist打开后,填好English Translation,看到Source text也是Mainwindow,总觉得怪怪的,但我没有理会。
QT 软件中英文切换

qm文件的生成

[edemon@CentOS internal]$  lrelease internal.pro
Updating '/home/edemon/workspace/internal/english.qm'...
Generated 8 translation(s) (8 finished and 0 unfinished)
Updating '/home/edemon/workspace/internal/chinese.qm'...
Generated 8 translation(s) (8 finished and 0 unfinished)

代码

首先,我们需要一个QTranslator *qtrans,它被安装在QApplication对象上。
点击语言选择按钮,触发加载语言包资源的槽函数。一旦bool QTranslator::load()成功了,MainWindow::changeEvent()自然顺势被调用,我们的UI更新函数void MainWindow::translateUi()可以放在changeEvent()里面。
关键功能函数:

functions effect
void QWidget::changeEvent(QEvent * event) [virtual protected] 处理更新事件
void languageChanged(); 加载语言包
void translateUi(); 更新UI

code:
main.cpp

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

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
a.installTranslator(w.qtrans);
return a.exec();
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTranslator>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
Q_OBJECT
protected:
void changeEvent(QEvent *);

public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
void translateUi();

public slots:
void languageChanged();

private:
Ui::MainWindow *ui;
public:
QTranslator *qtrans;
};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QGroupBox>

void MainWindow::changeEvent(QEvent *event)
{
if(event->type() == QEvent::LanguageChange) translateUi();
else QMainWindow::changeEvent(event);
}

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
qtrans = new QTranslator();

connect(ui->radioButton,SIGNAL(toggled(bool)),this,SLOT(languageChanged()));
connect(ui->radioButton_2,SIGNAL(toggled(bool)),this,SLOT(languageChanged()));
ui->radioButton->setChecked(true);
}

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

void MainWindow::translateUi()
{
ui->groupBox->setTitle(QObject::tr("language"));
ui->radioButton->setText(QObject::tr("english"));
ui->radioButton_2->setText(QObject::tr("chinese"));
setWindowTitle(QObject::tr("Mainwindow"));
}

void MainWindow::languageChanged()
{
if(ui->radioButton->isChecked())
qtrans->load("./english.qm");
else
qtrans->load("./chinese.qm");
}