将Csv格式文件转换为qm翻译文件,中间无需干预手动干预ts文件即可完成翻译文件的制作。
直接生成qm文件的工具
-
我们做Qt翻译文件时候一般使用
lupdate xx.pro
生成ts文件,再根据翻译使用Qt Linguist Manual工具修改ts后再使用lrelease*.ts
生成对应的qm文件。这一过程略显繁琐,作者的本意是简化该流程并能提供一个通用的翻译文本格式(csv)给翻译人员使用; - 本工具是通过csv翻译文件翻译到qm文件的工具,简单易用;
- 文尾附部分源码与源码地址。
实现
-
Csv解析实现使用
QList<QVariantMap>Csv::readAll();
接口解析csv格式,每一行的Csv格式数据为一个QList的item项,QVariantMap为第一行的标题与值的匹配; - Csv标题格式的定义,第一行的第一列固定为key值(该值为程序tr所应用的值),第一行的第二列至后都是语言的对应翻译。如:
key |
zh_CN |
en |
---|---|---|
start |
开始 |
Start |
end |
结束 |
End |
- convert主要作用是将csv源数据转换指定的翻译数据再输出到指定文件。如:
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文件;
static QString convertContext(QList<QVariantMap> source, QString contextTitle, QString language)
-
system("lrelease *.ts")
将当前目录下的ts文件转换为qm文件。
注意事项
- 当文件转换不成功需要查看translation.csv文件是否为空。
源码
目录
Csv2Qm/
├── Csv2Qm.pro
├── Csv.cpp
├── Csv.h
├── main.cpp
└── translation.csv
main.cpp
#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!!!";
qDebug()<<"Failed!!!";
return 0;
}
Csv.cpp
#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));