基于C++Qt5通过调用百度翻译API制作简易翻译工具

目录

    • 基于C++Qt5通过调用百度翻译API制作简易翻译工具
  • 写在前面
  • 步骤:
  • 1.注册百度翻译开放平台账号并开通翻译服务
  • 2.下载安装Qt5和QtCreator (windows)
    • 2.1下载Qt5
    • 2.2安装Qt5和QtCreator
    • 2.3创建项目
  • 3.封装生成Url类
    • 3.1百度翻译文档阅读
    • 3.2编写代码
  • 4.使用Qt5制作简易图形化界面
  • 5.编写逻辑代码
  • 补充:编码转码和一些报错处理
  • 总结一下


写在前面

先看看效果图

机缘巧合我发现了百度翻译API,也看了很多大佬用这个API做的项目。恰我的C++实验课的大作业是做一个项目,我就想到了做一个简易的翻译工具。

实现方法:通过封装一个生成url的类,对传入的需要翻译的内容生产相应的url,然会用QNetworkRequest类发送get请求,对请求返回的结果正则表达式解析和utf-8转码就得到了翻译结果
注意:翻译记录功能目前还没实现,不是因为很难,是因为很懒


步骤:

1.注册百度翻译开放平台账号并开通翻译服务

进入百度翻译开放平台官网,登录或注册


开通翻译服务

这里应该还要求实名认证才能开通服务


获取appid和密钥

2.下载安装Qt5和QtCreator (windows)

2.1下载Qt5

Qt5可以去下面的网站下载
[https://download.qt.io/archive/qt/]
(https://download.qt.io/archive/qt/)

也可以用迅雷下载我下载好的Qt5.12.10
链接:https://pan.xunlei/s/VMT-alRj3yvgWqrYNgWSPYeJA1
提取码:5b9p

2.2安装Qt5和QtCreator



注册后他会发邮件给你,按照它提示的步骤完成就行,我就不演示了,注册好后再回来。



接下来是选配环节了,建议电脑内存充足的选择全选,说不定以后能用上

下面的选择是安装Qtcreator

配置完成后点击下一步,来到下面的界面




这个安装要挺久的,反正我装了30分钟才装好。
装好之后在wimdows菜单找到刚刚创建的那个文件夹拉到最下面,如下图

到这里Qt5算是装好了,可以开始创建我们的项目了

2.3创建项目

打开QtCreator后
选择创建新项目






创建完成后


跑不了的可以按步骤再多试几次

最后按下面的步骤添加

QT       += network

这是访问必须的配置

到这里创建项目的准备工作就完成了

3.封装生成Url类

3.1百度翻译文档阅读

如果还没看过百度翻译api的文档建议先去看看,了解url的生产有助于下面代码的理解
百度翻译api文档

3.2编写代码

以下是实现生产url类的源码
Translator.h

#ifndef TANSLATOR_H
#define TANSLATOR_H

#include <iostream>
#include <QString>
#include <time.h>
#include <QTextCodec>
#include <QDebug>
#include <QObject>
#include "MD5.h"

using namespace std;
class Translator: public QObject
{
   
   
    Q_OBJECT
private:
    //支持7个翻译目标语种的标号
    string lan[7]={
   
   "en","zh","fra","de","kor","jp","th"};
    int index;      //选择语种的下标
    /* 因为百度翻译需要一个MD5加密的签名
     * 但是我找到的MD5加密的方法都只支持string类型
     * 所以这里先生产string类型url再转成Qstring
     * ps:不知道string和Qstring的区别可以去补一下课*/
    string myurl;   //存放string类型url
    string appid;   //appid
    QString qstr;   //传入的Qstring类型翻译的内容,需要转成string类型
    string q;       //string类型翻译的内容
    string from;    //翻译内容的语种,一般为‘auto’
    string to;      //翻译目标语种
    string salt;    //一串随机数,我是用时间戳当成随机数
    string secret_key;   //密钥
    string sign;    //MD5加密的签名
    QString url;    //Qstring类型url


public:
    Translator();     //默认构造函数
    Translator(const QString &);     //构造函数
    QString GetUrl();   //生产url的方法
    void SetQstr(const QString &);   //设置需要翻译内容的函数
    void SetIndex(const int&);      //设置翻译目标语种的函数



};

#endif // TANSLATOR_H

Translator.cpp

#include "Translator.h"

#if _MSC_VER >=1600    // MSVC2015>1899,对于MSVC2010以上版本都可以使用
#pragma execution_character_set("utf-8")
#endif
Translator::Translator(){
   
   

}
Translator::Translator(const QString &qerry)
    :qstr(qerry)
{
   
   
    q = qstr.toStdString();
    index = 0;
}

void Translator::SetQstr(const QString &qstring){
   
   
    qstr = qstring;
    q = qstr.toStdString();

}
void Translator::SetIndex(const int& in){
   
   
    index = in;
}
QString Translator::GetUrl(){
   
   
    //制作签名
    myurl = "https://fanyi-api.baidu/api/trans/vip/translate?";
    appid = "1212121212";  //你的appid
    from = "auto";
    to = lan[index];  //选择目标语种
    time_t myt = time(NULL);  //获取时间戳
    salt = to_string(myt);
    secret_key = "12121212212";  //你的密钥
    sign = "";
    //签名拼接
    sign.append(appid);
    sign.append(q);
    sign.append(salt);
    sign.append(secret_key);

    //签名MD5加密
    MD5 md5 = MD5(sign);
    sign = md5.outstr(32).c_str();

    //制作url
    myurl.append("&q=");
    myurl.append(q);
    myurl.append("&from=");
    myurl.append(from);
    myurl.append("&to=");
    myurl.append(to);
    myurl.append("&app&salt=");
    myurl.append(salt);
    myurl.append("&sign=");
    myurl.append(sign);
    //string转Qstring
    url=QString::fromStdString(myurl);
    return url;
}

下面附上MD5加密的源码,来源于网络
MD5.h

#include <iostream>
#include <windows.h>
using namespace std;
typedef unsigned char uchar;
typedef unsigned long ulong;

//步函数
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))
//循环左移
#define ROL(x, n) (((x) << (n)) | ((x) >> (32-(n))))
//  四轮操作
#define FF(a, b, c, d, mj, s, ti) { (a) += F ((b), (c), (d)) + (mj) + ti; (a) = ROL ((a), (s)); (a) += (b);}
#define GG(a, b, c, d, mj, s, ti) { (a) += G ((b), (c), (d)) + (mj) + ti; (a) = ROL ((a), (s)); (a) += (b);}
#define HH(a, b, c, d, mj, s, ti) { (a) += H ((b), (c), (d)) + (mj) + ti; (a) = ROL ((a), (s)); (a) += (b);}
#define II(a, b, c, d, mj, s, ti) { (a) += I ((b), (c), (d)) + (mj) + ti; (a) = ROL ((a), (s)); (a) += (b);}

class MD5 {
   
   
public:
    MD5(const string& str);
    const uchar* getDigest();	// 获取生成的摘要
    string outstr(int);			// 返回字符串
private:
    void generate(const uchar* input, int length);
    void change(const uchar block[64]);							// 四轮操作
    void encode(const ulong* input, uchar* output, int length);	// uchar to ulong
    void decode(const uchar* input, ulong* output, int length); // ulong to uchar

    ulong reg[4];		// ABCD
    ulong count[2];	    // 长度扩充
    uchar buffer[64];	// 输入buffer
    uchar digest[16];	// 生成的摘要
    bool end_flag;		// 结束标志
    static const uchar padding[64];
    static const char hex[16];
};

MD5.cpp

#include <MD5.h>

const uchar MD5::padding[64] = {
   
    0x80 };	// 初始化附加填充 1000 0000, 设置最高位为1
const char MD5::hex[16] = {
   
    '0', '1', '2', '3','4', '5', '6', '7','8', '9', 'a', 'b','c', 'd', 'e', 'f' };

MD5::MD5(const string& str) {
   
   
    end_flag = false;
    count[0] = count[1] = 0; // 重置bits个数
    // 初始化链接变量(高位->低位)
    /*
     * 错误的赋值,注意高低位
    reg[0] = 0x01234567;
    reg[1] = 0x89abcdef;
    reg[2] = 0xfedcba98;
    reg[3] = 0x76543210;
    */
    reg[0] = 0x67452301;
    reg[1] = 0xefcdab89;
    reg[2] = 0x98badcfe;
    reg[3] = 0x10325476;
    generate((uchar*)const_cast<char*>(str.c_str()), str.length());
}

/**
 * 获取摘要
 */
const uchar* MD5::getDigest() {
   
   
    if (!end_flag) {
   
   
        end_flag = true;
        uchar bits[8];
        ulong _reg[4];		// 旧reg
        ulong _count[2];	// 旧count
        ulong index, padLen;
        memcpy(_reg, reg, 16);		// 复制内存,将_reg内存地址的起始位置开始拷贝16字节到reg起始位置中
        memcpy(_count, count, 8);	// 将原始消息长度以64比特(8字节)复制到count后
        encode(count, bits, 8);
        /* Pad out to 56 mod 64. */
        index = (ulong)((count[0] >> 3) & 0x3f);
        padLen = (index < 56) ? (56 - index) : (120 - index);
        generate(padding, padLen);
        generate(bits, 8);
        encode(reg, digest, 16);
        /* 重新存储reg和count */
        memcpy(reg, _reg, 16);
        memcpy(count, _count, 8);
    }
    return digest;
}


void MD5::generate(const uchar* input, int length) {
   
   
    ulong i, index, partLen;
    end_flag = false;
    index = (ulong)((count[0] >> 3) & 0x3f);
    if ((count[0] += ((ulong)length << 3