QT 翻译ts文件与Excel文件互转
技术:Windows + QT 5.3.2 + EXCEL + XML
概述
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)) { } else { 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); } else { 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文件就可以在程序中使用。
本实例支付的费用只是购买源码的费用,如有疑问欢迎在文末留言交流,如需作者在线代码指导、定制等,在作者开启付费服务后,可以点击“购买服务”进行实时联系,请知悉,谢谢
手机上随时阅读、收藏该文章 ?请扫下方二维码