发布QtCsv文件转语言翻译文件工具

将Csv格式文件转换为qm翻译文件,中间无需干预手动干预ts文件即可完成翻译文件的制作。

直接生成qm文件的工具

  1. 我们做Qt翻译文件时候一般使用lupdate xx.pro生成ts文件,再根据翻译使用Qt Linguist Manual工具修改ts后再使用lrelease *.ts生成对应的qm文件。这一过程略显繁琐,作者的本意是简化该流程并能提供一个通用的翻译文本格式(csv)给翻译人员使用;
  2. 本工具是通过csv翻译文件翻译到qm文件的工具,简单易用;
  3. 文尾附部分源码与源码地址。

实现

  • Csv解析实现使用QList<QVariantMap> Csv::readAll();接口解析csv格式,每一行的Csv格式数据为一个QList的item项,QVariantMap为第一行的标题与值的匹配;
  • Csv标题格式的定义,第一行的第一列固定为key值(该值为程序tr所应用的值),第一行的第二列至后都是语言的对应翻译。如:
key zh_CN en
start 开始 Start
end 结束 End
  • convert主要作用是将csv源数据转换指定的翻译数据再输出到指定文件。如:

    1
    2
    3
    static bool convert(QList<QVariantMap> source, QString language, QString outputFile)
    convert(csvContexts, "zh_CN", "zh_CN.ts"); //将zh_CN列翻译转换为zh_CN.ts文件
    convert(csvContexts, "en", "en.ts"); //将en列翻译转换为en.ts文件
  • convertContext主要作用为指定格式的ts文件;

    1
    static QString convertContext(QList<QVariantMap> source, QString contextTitle, QString language)
  • system("lrelease *.ts")将当前目录下的ts文件转换为qm文件。

注意事项

  • 当文件转换不成功需要查看translation.csv文件是否为空。

源码

目录

1
2
3
4
5
6
Csv2Qm/
├── Csv2Qm.pro
├── Csv.cpp
├── Csv.h
├── main.cpp
└── translation.csv

main.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include "Csv.h"

#include <QCoreApplication>
#include <QJsonDocument>
#include <QFile>
#include <QDebug>

const QStringList Languages = {
"zh_CN", "en"
};

static QString convertContext(QList<QVariantMap> source, QString contextTitle, QString language)
{
QString context = QString("<context>\n");
context += QString("\t<name>%1</name>\n").arg(contextTitle);
for (int i = 0; i < source.count(); i++) {
QVariantMap item;
item["source"] = source.at(i).value("key").toString();
if (Languages.contains(language)) {
item["translation"] = source.at(i).value(language).toString();
}
else {
qDebug()<<"Failed!!!";
exit(-1);
}

context += QString("\t<message>\n\t\t<source>%1</source>\n\t\t<translation>%2</translation>\n\t</message>\n")
.arg(item["source"].toString())
.arg(item["translation"].toString());
}
context += QString("</context>\n");
return context;
}

static bool convert(QList<QVariantMap> source, QString language, QString outputFile)
{
QString head = QString("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n") +
QString("<!DOCTYPE TS>\n") +
QString("<TS version=\"2.0\" language=\"%1\">\n").arg(language);

QString content;
content += convertContext(source, "QObject", language);

QString tail = QString("</TS>");

QString result = head + content + tail;
QFile file(outputFile);
file.open(QFile::WriteOnly);
file.write(result.toUtf8());
file.close();
}

int main(int argc, char *argv[])
{
QString file = "translation.csv";
if (argc == 2) {
file = argv[1];
}

Csv csvor;
csvor.open(file);

QList<QVariantMap> csvContexts = csvor.readAll();

if (csvContexts.isEmpty()) {
qDebug()<<"csvContexts Failed!!!";
return -1;
}

convert(csvContexts, "zh_CN", "zh_CN.ts");
convert(csvContexts, "en", "en.ts");

if (system("lrelease *.ts") == 0)
qDebug()<<"Success!!!";
else
qDebug()<<"Failed!!!";

return 0;
}

Csv.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include "Csv.h"

#include <QStringList>
#include <QDebug>

Csv::Csv()
{

}

bool Csv::open(const QString &fileName)
{
m_file = new QFile(fileName);
if (!m_file->open(QIODevice::ReadWrite)) {
qDebug()<<"[error] "<<QString("Open %1 file failed!").arg(fileName);
return false;
}
else {
return true;
}
}

QList<QVariantMap> Csv::readAll()
{
QList<QVariantMap> data;

if (m_file == NULL)
return data;

bool isFirstLine = true;
QStringList titles;

while (!m_file->atEnd()) {
QByteArray line = m_file->readLine();
QStringList contents = QString::fromLocal8Bit(line)
.simplified()
.split(',', QString::SkipEmptyParts);
if (isFirstLine) {
isFirstLine = false;
titles = contents;
continue;
}

QVariantMap item;
for (int i = 0; i < contents.count(); i++) {
if (i >= titles.count())
continue;

item.insert(item.find(titles[i]), titles[i], contents.at(i));
}

data.append(item);
}

return data;
}

translation.csv 文件

key zh_CN en
start 开始 Start
end 结束 End
open 打开 Open
close 关闭 Close

源码地址:

1
https://github.com/aeagean/Csv2Qm.git