项目要求有多国语言翻译,但是手动的去复制粘贴翻译显然不是合理的,组里有人写过类似工具,但是我这里没有源码,又想根据我的需求定制一些功能,所以借鉴现有的界面,如下图
下面先搞定核心功能:百度翻译api的调用和对返回的数据进行处理。
根据百度通用翻译API接入文档得知,通用翻译API通过HTTP接口对外提供多语种互译服务。您只需要通过调用通用翻译API,传入待翻译的内容,并指定要翻译的源语言(支持源语言语种自动检测)和目标语言种类,就可以得到相应的翻译结果。
下面是我写的简单zh -> en 实现,主要是这一部分的代码:
主要代码:
///下面是请求部分
int a=rand();
char salt[60];
QString MD5;
QNetworkAccessManager *manager=new QNetworkAccessManager(this);
sprintf(salt,"%d",a);//主要功能是把格式化的数据写入某个字符串中
q=ui->plainTextEdit_IN->toPlainText();
sign=QString("你的appid%1%2你的秘钥").arg(q).arg(salt);//连接加密文件
str = QCryptographicHash::hash(sign.toUtf8(),QCryptographicHash::Md5);
MD5.append(str.toHex());//生成md5加密文件
myurl=QString("http://api.fanyi.baidu.com/api/trans/vip/translate?"
"q=%1&from=%2&to=%3&appid=你的appid"//appid=2019xxxxxx
"&salt=%4&sign=%5").arg(q).arg(from).arg(to).arg(salt).arg(MD5);
/*链接上传文本*/
manager->get(QNetworkRequest(QUrl(myurl)));//发送上传;
connect(manager,&QNetworkAccessManager::finished,this,&Widget::replyFinished);
//得到返回值触发槽函数int replyFinished()
//*************************************************************************************
///int replyFinished()槽函数
int Widget::replyFinished(QNetworkReply *reply)
{
connect(reply,&QNetworkReply::readyRead,[=](){
qDebug() << "get QNetworkReply::readyRead";
});
qDebug() << reply << reply->rawHeaderList() << reply->rawHeaderPairs();
QJsonParseError jsonError;
QByteArray all = reply->readAll();//获得api返回值
qDebug() << all;
/* 大概是这样的一个东西
{"from":"en","to":"zh","trans_result":[{"src":"apple","dst":"\u82f9\u679c"}]}
你需要解码 */
QJsonDocument json = QJsonDocument::fromJson(all, &jsonError);
qDebug() << json;
QJsonObject object = json.object();//json转码;
qDebug() << object;
QString a;
if(object.contains("error_code"))//传过来错误
{
a=object.value("error_code").toString();
if (a==52001) {
a="5200 请求超时 重试";
}
else if(a=="52002")
{
a="52002 系统错误 重试";
}
else if(a=="54000")
{
a="54000 必填参数为空";
}
else if(a=="54001")
{
a="54001 签名错误";
}
else if(a=="54003")
{
a="54003 速度过快访问频率受限";//({"error_code":"54003","error_msg":"Invalid Access Limit"})
}
else if(a=="54004")
{
a="54004 账户余额不足";
}
else if(a=="54005")
{
a="54005 请求频繁";
}
else if(a=="58002")
{
a="58002 服务关闭";
}
else{
a="其他错误";
}
ui->plainTextEdit_Out->appendPlainText(a);
}
else {
QJsonArray value = object.value("trans_result").toArray();//一次解码
/*
{"from":"en","to":"zh",
"trans_result":[{"src":"apple","dst":"\u82f9\u679c"}]}
第一次解码
*/
qDebug() << value;
for (int var = 0; var < value.size(); ++var) {
QJsonObject object1=value.at(var).toObject();//二次解码,开[]括号;
/*
{"src":"apple","dst":"\u82f9\u679c"}
第二次解码
*/
qDebug() << object1;
from=object.value("from").toString();
a=object1.value("dst").toString();//输出得到翻译结果
ui->plainTextEdit_Out->appendPlainText(a);
}
}
reply->deleteLater();
return 1;
}
关于ts文件的翻译部分:
ts文件打开后会发现它其实是xml的文本形式。所以我们可以获取ts文件里面的
<message>
<location filename="../dialog-class/aboutdialog.ui" line="69"/>
<source>确定</source>
<translation>OK</translation>
</message>
<source>标签进行待翻译文本获取。翻译后可以对<translation>写入翻译后的文本。
我主要用QDomDocument进行ts,html,xml文件的读写操作,例如:
void CQtTsMessageNodeView::AppendMessageNode(QDomNode node)
{
CStandardItem * messageItem = new CStandardItem;
messageItem->setEditable(false);
messageItem->setData(QString("信息节点") + QString().setNum(m_model->rowCount() + 1), Qt::DisplayRole);
messageItem->SetDomNode(node);
m_model->appendRow(messageItem);
QDomNodeList sourceNodeList = node.toElement().elementsByTagName(QString("source"));
if(! sourceNodeList.isEmpty())
{
CStandardItem * messageSourceItem = new CStandardItem;
messageSourceItem->setEditable(false);
messageSourceItem->SetDomNode(sourceNodeList.at(0));
messageSourceItem->setData(QString("资源:") + sourceNodeList.at(0).toElement().text(), Qt::DisplayRole);
messageItem->appendRow(messageSourceItem);
}
QDomNodeList transNodeList = node.toElement().elementsByTagName(QString("translation"));
if(! transNodeList.isEmpty())
{
CStandardItem * transSourceItem = new CStandardItem;
transSourceItem->setEditable(false);
transSourceItem->SetDomNode(transNodeList.at(0));
transSourceItem->setData(QString("翻译:") + transNodeList.at(0).toElement().text(), Qt::DisplayRole);
messageItem->appendRow(transSourceItem);
}
}
这是部分读取ts文件的待翻译信息还有翻译好的信息,行程CStandardItem ,显示在左边ListView栏。
void MainWindow::SlotReplyReadWithItem()
{
m_transCount--;
m_progressBar->setValue(m_progressBar->maximum() - m_transCount);
QNetworkReply *reply = (QNetworkReply *)sender();
///通过网络回复类读取全部返回json数据
QByteArray buf;
buf = reply->readAll();
///利用json documnet类存放数据
QJsonDocument document = QJsonDocument::fromJson(buf);
///取出文档类中的object
QJsonObject object = document.object();
///将object转化为变量map
QVariantMap map = object.toVariantMap();
///判断map中是否包含错误信息
if(map.contains(QString("error_code")))
{
MessageOutErrorStr(map.value("error_msg").toString() + " 错误码: " + map.value("error_code").toString());
CStandardItem * item = m_qtdockView->GetItemFromVar(sender()->property("item"));
emit SignalAcceptItemTransData(item, QString());
if(m_transCount == 0)
{
qDebug()<<"finish";
return SignalTransQtTsFinish();
}
return;
}
if(! map.contains(QString("trans_result")))
{
MessageOutErrorStr(QString("未知错误类型,无翻译文本返回"));
CStandardItem * item = m_qtdockView->GetItemFromVar(sender()->property("item"));
emit SignalAcceptItemTransData(item, QString());
if(m_transCount == 0)
{
qDebug()<<"finish";
return SignalTransQtTsFinish();
}
return;
}
///取出map中的翻译结果变量
QVariant var = map.value(QString("trans_result"));
///转话为变量列表
QVariantList varList = var.toList();
///申请临时翻译文本与资源文本映射
QVariantMap dstAndSrcMap;
dstAndSrcMap.clear();
///从链表中取出赋值给临时映射
foreach (QVariant varTemp, varList)
{
if(varTemp.type() == QVariant::Map)
{
dstAndSrcMap = varTemp.toMap();
break;
}
}
///将映射中的翻译文本取出写入显示区
m_receiveTextShowEdit->append(QString("接受信息:") + dstAndSrcMap.value("dst").toString());
map.insert(sender()->property("key").toString(), dstAndSrcMap.value("dst").toString());
sender()->deleteLater();
CStandardItem * item = m_qtdockView->GetItemFromVar(sender()->property("item"));
emit SignalAcceptItemTransData(item, dstAndSrcMap.value("dst").toString());
if(m_transCount == 0)
{
qDebug()<<"finish";
return SignalTransQtTsFinish();
}
}
这是整理后的处理请求回来的翻译信息,储存和显示在程序界面上。
以上就是自动翻译工具的主要模块介绍,主要是适配公司项目的说明书翻译功能,除去繁琐的赋值粘贴。
翻译完成后,最好使用Qt的语言家工具对翻译的结果进行校对。
现在官网支持200多种语言翻译,可以满足需求。也可以考虑对接谷歌翻译,不过要收费。百度也有垂直领域的翻译也是要收费。