QT 翻译文件虽然可以使用linguist.exe进行翻译,但是这个比较专业,复杂,不太适合把它直接提供给客户进行翻译,而该例子是则讲述如何将QT翻译文件.ts文件转换成excel文件,得到excel文件后可将之提供给客户翻译,之后再讲翻译好的excel文件转换成.ts文件.
我们的
目的是将.ts翻译文件与excel文件相互转换
,.ts是xml格式的,所以我们需要使用Qt的解析XML相关的几个类和解析excel文件相关的几个类,它们分别是:
QDomDocument
QDomElement
QDomNode
QDomText
QDomNodeList
QAxObject
一. 运行结果
二. 将Ts转换成excel实现过程
1. 创建QDomDocument对象
QFile file( m_tsPath );
if( !file.open( QFile::ReadOnly | QFile::Text ) ) //打开.ts文件
qDebug() << QObject::tr("error::ParserXML->OpenXmlFile->file.open->%s\n") << tsPath();
return false;
QDomDocument t_doc;
if( !t_doc.setContent( &file ) )
qDebug() << QObject::tr("error::ParserXML->OpenXmlFile->doc.setContent\n") << tsPath();
file.close();
return false;
}
2. 读取ts文件中的内容到QHash容器中
QDomElement root = t_doc.documentElement();
QDomNode n = root.firstChild();
while ( !n.isNull() )
QDomElement e = n.toElement();
if( !e.isNull())
if( e.nodeName() == "context" )
QDomNodeList list = e.childNodes(); //获得元素e的所有子节点的列表
for(int a=0; a<list.count(); a++) //遍历该列表
QDomNode node = list.at(a);
if(node.isElement())
if( node.nodeName() == "message" )
QDomNodeList list2 = node.childNodes(); //获得元素node的所有子节点的列表
QString curText;
for(int i=0; i<list2.count(); i++) //遍历该列表
QDomNode node2 = list2.at(i);
if(node2.isElement())
if( node2.nodeName() == "source" )
curText = node2.firstChild().toText().data();
else if( node2.nodeName() == "translation" )
if (isDigitStr(curText) || curText.isEmpty() || curText.startsWith("ID_") || curText.endsWith("_ID") \
|| (curText.endsWith("Form") && curText.length() > 4))
else if (m_excludeVector.contains(curText))
languageHash.insert(curText, node2.firstChild().toText().data());
else if( node.nodeName() == "name" )
n = n.nextSibling();
}
3. 打开excel文件,打开对应的sheet
QAxObject excel("Excel.Application");//连接Excel控件
excel.setProperty("Visible", false);// 不显示窗体
excel.setProperty("DisplayAlerts", false); //不显示任何警告信息。如果为true, 那么关闭时会出现类似"文件已修改,是否保存"的提示
QAxObject* workbooks = excel.querySubObject("WorkBooks"); // 获取工作簿集合
if (!workbooks)
return false;
workbooks->dynamicCall("Add"); // 新建一个工作簿
QAxObject* workbook = excel.querySubObject("ActiveWorkBook"); // 获取当前工作簿
if (!workbook)
return false;
QAxObject* worksheet = workbook->querySubObject("WorkSheets(int)", 1); // 获取工作表集合的工作表1, 即sheet1
if (!worksheet)
return false;
}
4. 保存QHash容器中的内容到Excel中
QAxObject* cell = NULL;
int rowCount = 1;
QHashIterator<QString, QString> iter(languageHash);
while(iter.hasNext())
iter.next();
cell = worksheet->querySubObject("Cells(int, int)", rowCount, 1);
if (cell)
cell->dynamicCall("SetValue(conts QVariant&)", iter.key()); // 设置单元格的值
cell = worksheet->querySubObject("Cells(int, int)", rowCount, 2);
if (cell)
cell->dynamicCall("SetValue(conts QVariant&)", iter.value()); // 设置单元格的值
rowCount++;
workbook->dynamicCall("SaveAs(const QString&)", QDir::toNativeSeparators(m_excelPath)); //保存到filepath // 注意一定要用QDir::toNativeSeparators, 将路径中的"/"转换为"\", 不然一定保存不了
workbook->dynamicCall("Close (Boolean)", false); //关闭文件
excel.dynamicCall("Quit(void)"); //退出
三. 使用excel打开第二步得到的文件,并将翻译结果写在第二列
四. 将Excel文档转换成ts文件
1. 打开excel文档,这与2.3相同,在这里不再重复介绍
2.获取Excel文档的内容,保存到QHash容器中
QAxObject* cell = NULL;
QString source;
QString dest;
for(int i=intRowStart;i<intRow+intRowStart;i++)
cell = worksheet->querySubObject("Cells(int, int)", i, 1); //获单元格值
source = cell->dynamicCall("Value2()").toString();
cell = worksheet->querySubObject("Cells(int, int)", i, 2); //获单元格值
dest = cell->dynamicCall("Value2()").toString();
languageHash.insert(source, dest);
}
3.打开ts文件,这一步与2.1相同
4. 保存QHash容器中的内容到ts文件中
QDomElement root = t_doc.documentElement();
QDomNode n = root.firstChild();
while ( !n.isNull() )
QDomElement e = n.toElement();
if( !e.isNull())
if( e.nodeName() == "context" )
QDomNodeList list = e.childNodes(); //获得元素e的所有子节点的列表
for(int a=0; a<list.count(); a++) //遍历该列表
QDomNode node = list.at(a);
if(node.isElement())
if( node.nodeName() == "message" )
QDomNodeList list2 = node.childNodes(); //获得元素node的所有子节点的列表
QString curText;
for(int i=0; i<list2.count(); i++) //遍历该列表
QDomNode node2 = list2.at(i);
if(node2.isElement())
if( node2.nodeName() == "source" )
curText = node2.firstChild().toText().data();
else if( node2.nodeName() == "translation" )
if (languageHash.contains(curText) && !languageHash.value(curText).isEmpty())
if (node2.hasChildNodes())
QDomNode oldNode = node2.firstChild();
node2.firstChild().setNodeValue(languageHash.value(curText));
QDomNode newNode = node2.firstChild();
node2.replaceChild(newNode, oldNode);
QDomElement e = node2.toElement();
e.removeAttribute("type");
QDomText newNode;
newNode = t_doc.createTextNode(languageHash.value(curText));
node2.appendChild(newNode);
else if( node.nodeName() == "name" )
n = n.nextSibling();
if(!file.open(QFile::WriteOnly|QFile::Truncate))
return ;
QTextStream ts(&file);
ts.reset();
ts.setCodec("utf-8");
t_doc.save(ts, 4, QDomNode::EncodingFromTextStream);
file.close();
五. 项目结构图
六. 使用介绍
选择好相应的.ts文件和excel文件,exclue file则是一些不想要翻译的文字的集合,可以是一个空文件,选好文件之后,点击ts to excel按钮,得到excel文件,然后可以在excel中进行翻译,将翻译结果写在excel文档的第二列,翻译完成后,点击excel to ts按钮,将excel文件转换成.ts文件。.ts文件放到相应的qt项目中,使用qt语言家生产.qm文件就可以在程序中使用。