一个Qt调用百度翻译API进行文本翻译的程序记录,辅助ts文件进行翻译。

项目要求有多国语言翻译,但是手动的去复制粘贴翻译显然不是合理的,组里有人写过类似工具,但是我这里没有源码,又想根据我的需求定制一些功能,所以借鉴现有的界面,如下图

下面先搞定核心功能:百度翻译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多种语言翻译,可以满足需求。也可以考虑对接谷歌翻译,不过要收费。百度也有垂直领域的翻译也是要收费。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值