本文内容学习自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
运行效果
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。
如下:
修改的对应项将问号点成对勾,不然ts文件一直显示translation type=”unfinished”
如下:
<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,总觉得怪怪的,但我没有理会。
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");
}