基于C++Qt5通过调用百度翻译API制作简易翻译工具
目录
写在前面
先看看效果图
机缘巧合我发现了百度翻译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.com/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.com/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("&appid=");
myurl.append(appid);
myurl.append("&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)) < ((ulong)length << 3))
count[1]++;
count[1] += ((ulong)length >> 29);
partLen = 64 - index;
if (length >= partLen) {
memcpy(&buffer[index], input, partLen);
change(buffer); //分组处理,四轮操作
for (i = partLen; i + 63 < length; i += 64)
change(&input[i]);
index = 0;
}
else {
i = 0;
}
// 内存拷贝
memcpy(&buffer[index], &input[i], length - i);
}
/**
* 四轮变换操作
*/
void MD5::change(const uchar block[64]) {
ulong a = reg[0],
b = reg[1],
c = reg[2],
d = reg[3],
m[16];
decode(block, m, 64); // uchar 转 ulong
FF(a, b, c, d, m[0], 7, 0xd76aa478);
FF(d, a, b, c, m[1], 12, 0xe8c7b756);
FF(c, d, a, b, m[2], 17, 0x242070db);
FF(b, c, d, a, m[3], 22, 0xc1bdceee);
FF(a, b, c, d, m[4], 7, 0xf57c0faf);
FF(d, a, b, c, m[5], 12, 0x4787c62a);
FF(c, d, a, b, m[6], 17, 0xa8304613);
FF(b, c, d, a, m[7], 22, 0xfd469501);
FF(a, b, c, d, m[8], 7, 0x698098d8);
FF(d, a, b, c, m[9], 12, 0x8b44f7af);
FF(c, d, a, b, m[10], 17, 0xffff5bb1);
FF(b, c, d, a, m[11], 22, 0x895cd7be);
FF(a, b, c, d, m[12], 7, 0x6b901122);
FF(d, a, b, c, m[13], 12, 0xfd987193);
FF(c, d, a, b, m[14], 17, 0xa679438e);
FF(b, c, d, a, m[15], 22, 0x49b40821);
GG(a, b, c, d, m[1], 5, 0xf61e2562);
GG(d, a, b, c, m[6], 9, 0xc040b340);
GG(c, d, a, b, m[11], 14, 0x265e5a51);
GG(b, c, d, a, m[0], 20, 0xe9b6c7aa);
GG(a, b, c, d, m[5], 5, 0xd62f105d);
GG(d, a, b, c, m[10], 9, 0x2441453);
GG(c, d, a, b, m[15], 14, 0xd8a1e681);
GG(b, c, d, a, m[4], 20, 0xe7d3fbc8);
GG(a, b, c, d, m[9], 5, 0x21e1cde6);
GG(d, a, b, c, m[14], 9, 0xc33707d6);
GG(c, d, a, b, m[3], 14, 0xf4d50d87);
GG(b, c, d, a, m[8], 20, 0x455a14ed);
GG(a, b, c, d, m[13], 5, 0xa9e3e905);
GG(d, a, b, c, m[2], 9, 0xfcefa3f8);
GG(c, d, a, b, m[7], 14, 0x676f02d9);
GG(b, c, d, a, m[12], 20, 0x8d2a4c8a);
HH(a, b, c, d, m[5], 4, 0xfffa3942);
HH(d, a, b, c, m[8], 11, 0x8771f681);
HH(c, d, a, b, m[11], 16, 0x6d9d6122);
HH(b, c, d, a, m[14], 23, 0xfde5380c);
HH(a, b, c, d, m[1], 4, 0xa4beea44);
HH(d, a, b, c, m[4], 11, 0x4bdecfa9);
HH(c, d, a, b, m[7], 16, 0xf6bb4b60);
HH(b, c, d, a, m[10], 23, 0xbebfbc70);
HH(a, b, c, d, m[13], 4, 0x289b7ec6);
HH(d, a, b, c, m[0], 11, 0xeaa127fa);
HH(c, d, a, b, m[3], 16, 0xd4ef3085);
HH(b, c, d, a, m[6], 23, 0x4881d05);
HH(a, b, c, d, m[9], 4, 0xd9d4d039);
HH(d, a, b, c, m[12], 11, 0xe6db99e5);
HH(c, d, a, b, m[15], 16, 0x1fa27cf8);
HH(b, c, d, a, m[2], 23, 0xc4ac5665);
II(a, b, c, d, m[0], 6, 0xf4292244);
II(d, a, b, c, m[7], 10, 0x432aff97);
II(c, d, a, b, m[14], 15, 0xab9423a7);
II(b, c, d, a, m[5], 21, 0xfc93a039);
II(a, b, c, d, m[12], 6, 0x655b59c3);
II(d, a, b, c, m[3], 10, 0x8f0ccc92);
II(c, d, a, b, m[10], 15, 0xffeff47d);
II(b, c, d, a, m[1], 21, 0x85845dd1);
II(a, b, c, d, m[8], 6, 0x6fa87e4f);
II(d, a, b, c, m[15], 10, 0xfe2ce6e0);
II(c, d, a, b, m[6], 15, 0xa3014314);
II(b, c, d, a, m[13], 21, 0x4e0811a1);
II(a, b, c, d, m[4], 6, 0xf7537e82);
II(d, a, b, c, m[11], 10, 0xbd3af235);
II(c, d, a, b, m[2], 15, 0x2ad7d2bb);
II(b, c, d, a, m[9], 21, 0xeb86d391);
reg[0] += a;
reg[1] += b;
reg[2] += c;
reg[3] += d;
}
/**
* ulong 转 uchar
*/
void MD5::encode(const ulong* input, uchar* output, int length) {
for (int i = 0, j = 0; j < length; i++, j += 4) {
output[j] = (uchar)(input[i] & 0xff);
output[j + 1] = (uchar)((input[i] >> 8) & 0xff);
output[j + 2] = (uchar)((input[i] >> 16) & 0xff);
output[j + 3] = (uchar)((input[i] >> 24) & 0xff);
}
}
/**
* uchar 转 ulong
*/
void MD5::decode(const uchar* input, ulong* output, int length) {
for (int i = 0, j = 0; j < length; i++, j += 4) {
output[i] = ((ulong)input[j]) | (((ulong)input[j + 1]) << 8) | (((ulong)input[j + 2]) << 16) | (((ulong)input[j + 3]) << 24);
}
}
string MD5::outstr(int length = 32) {
const uchar* input = getDigest();
string str;
//str.reserve(length << 1);
for (int i = 0; i < 16; i++) {
int t = input[i];
int a = t / 16;
int b = t % 16;
str.append(1, hex[a]);
str.append(1, hex[b]);
}
if (16 == length) {
str = str.substr(9 - 1, 16);
}
return str;
}
/**
* GB2312转Unicode,解决中文出错问题
* 此处代码来源于网络。
*/
string G2U(string str) {
int nwLen = ::MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, NULL, 0);
wchar_t* pwBuf = new wchar_t[nwLen + 1];
ZeroMemory(pwBuf, nwLen * 2 + 2);
::MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.length(), pwBuf, nwLen);
int nLen = ::WideCharToMultiByte(CP_UTF8, 0, pwBuf, -1, NULL, NULL, NULL, NULL);
char* pBuf = new char[nLen + 1];
ZeroMemory(pBuf, nLen + 1);
::WideCharToMultiByte(CP_UTF8, 0, pwBuf, nwLen, pBuf, nLen, NULL, NULL);
std::string retStr(pBuf);
delete[]pwBuf;
delete[]pBuf;
pwBuf = NULL;
pBuf = NULL;
return retStr;
}
4.使用Qt5制作简易图形化界面
在设计中简单设计自己喜欢的界面,需要注意的是要记住部分控件的id,如编辑框和按钮等,建议自己重命名一下
拖拽设计这里就不演示了,挺简单的
下面附上ui代码
mainwindow.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>640</width>
<height>581</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>640</width>
<height>581</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>640</width>
<height>581</height>
</size>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QComboBox" name="comboBox">
<property name="geometry">
<rect>
<x>450</x>
<y>190</y>
<width>121</width>
<height>31</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>121</width>
<height>31</height>
</size>
</property>
<item>
<property name="text">
<string>英语</string>
</property>
</item>
<item>
<property name="text">
<string>中文</string>
</property>
</item>
<item>
<property name="text">
<string>法语</string>
</property>
</item>
<item>
<property name="text">
<string>德语</string>
</property>
</item>
<item>
<property name="text">
<string>韩语</string>
</property>
</item>
<item>
<property name="text">
<string>日语</string>
</property>
</item>
<item>
<property name="text">
<string>泰语</string>
</property>
</item>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>450</x>
<y>30</y>
<width>91</width>
<height>21</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>91</width>
<height>21</height>
</size>
</property>
<property name="text">
<string>翻译记录:</string>
</property>
</widget>
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>450</x>
<y>150</y>
<width>121</width>
<height>31</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>121</width>
<height>31</height>
</size>
</property>
<property name="text">
<string>目标语种:</string>
</property>
</widget>
<widget class="QLabel" name="labeltips">
<property name="geometry">
<rect>
<x>450</x>
<y>49</y>
<width>131</width>
<height>101</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>131</width>
<height>101</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="textFormat">
<enum>Qt::AutoText</enum>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
<widget class="QPushButton" name="pushButton">
<property name="geometry">
<rect>
<x>450</x>
<y>260</y>
<width>161</width>
<height>81</height>
</rect>
</property>
<property name="text">
<string>翻译</string>
</property>
</widget>
<widget class="QSplitter" name="splitter_3">
<property name="geometry">
<rect>
<x>40</x>
<y>10</y>
<width>381</width>
<height>541</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<widget class="QSplitter" name="splitter">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<widget class="QLabel" name="label">
<property name="minimumSize">
<size>
<width>61</width>
<height>20</height>
</size>
</property>
<property name="text">
<string>原文:</string>
</property>
</widget>
<widget class="QTextEdit" name="textEdit">
<property name="undoRedoEnabled">
<bool>true</bool>
</property>
<property name="html">
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
p, li { white-space: pre-wrap; }
</style></head><body style=" font-family:'SimSun'; font-size:9pt; font-weight:400; font-style:normal;">
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html></string>
</property>
<property name="placeholderText">
<string>请输入</string>
</property>
</widget>
</widget>
<widget class="QSplitter" name="splitter_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<widget class="QLabel" name="label_5">
<property name="minimumSize">
<size>
<width>71</width>
<height>21</height>
</size>
</property>
<property name="text">
<string>译文:</string>
</property>
</widget>
<widget class="QTextEdit" name="textdisplay">
<property name="enabled">
<bool>true</bool>
</property>
</widget>
</widget>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>640</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>
5.编写逻辑代码
附上逻辑源码
里面注释清晰明了
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <regex>
#include <atlstr.h>
#include <vector>
#include <QMainWindow>
#include <QNetworkReply>
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr); //构造函数
QString unicodeToUtf8(QString); //unicode转utf-8,用于处理返回数据
QString myregex(const QString &str); //正则处理函数,用于解析返回数据,这里也可以使用json解析数据
~MainWindow();
private:
Ui::MainWindow *ui; //初始化ui
public slots:
void parsingJson(QNetworkReply * reply); //get请求完成后触发槽函数
void ClickButton(); //翻译按钮触发槽函数
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#if _MSC_VER >=1600 // MSVC2015>1899,对于MSVC2010以上版本都可以使用
#pragma execution_character_set("utf-8") //设置编码格式为utf-8,可能会出现乱码
#endif
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
//初始化ui
ui->setupUi(this);
setWindowTitle("随便翻译"); //设置窗口标题
setFixedSize(640,581); //设置窗口大小
ui->labeltips->setText("共翻译:10次\n\n成功:5次"); //懒得实现的翻译记录功能
ui->textdisplay->setReadOnly(true); //我是用TextEdit来展示翻译结果,所以这里要设置为只读模式
connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(ClickButton())); //翻译按钮信号和槽函数连接,这里是qt4风格的连接
}
void MainWindow::ClickButton(){
int index=0;
index=ui->comboBox->currentIndex(); //获取下拉选择框中选中的语种
QString str = ui->textEdit->toPlainText(); //获取输入框中的内容
// qDebug()<<str;
translator.SetQstr(str); //传入需要翻译
translator.SetIndex(index); //传入下标
QString url = translator.GetUrl(); //获取url
// qDebug()<<url;
//1. 创建一个请求
QNetworkRequest request;
request.setUrl(QUrl(url));
//2. 创建一个管理器
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
// 3. 连接请求结束信号
connect(manager,SIGNAL(finished(QNetworkReply*)),this,SLOT(parsingJson(QNetworkReply*)));
//4. 发送GET请求
manager->get(request);
}
//槽函数,处理返回的数据
void MainWindow::parsingJson(QNetworkReply * reply)
{
if(reply->error() == QNetworkReply::NoError){
//判断是否请求成功
QString all = reply->readAll(); //读出返回数据
qDebug() << all ; //打印出来会发现中文和一些外文是Unicode编码的转义字符,如\\u187d
QString re = myregex(all); //解析出翻译结果,即取出dst字段
qDebug()<<re;
QString res = unicodeToUtf8(re); //unicode转utf8
qDebug()<<res ;
ui->textdisplay->setText(res); //更新控件上的内容
}
else{
qDebug() << reply->errorString() << " error " << reply->error();
}
}
QString MainWindow::myregex(const QString &qstr){
//正则解析函数,这里就不解释了,不会正则的可以去补一下课
string ans;
string str = qstr.toStdString();
string pattern = "\"(.+?)\"";
regex e("\\[(.*)\\]");
regex r(pattern);
smatch m;
regex_search(str, m, e);
string temp = m[1];
auto res = vector<string>(9);
sregex_iterator pos(temp.cbegin(), temp.cend(), r), end;
for (; pos != end; ++pos) {
res.push_back(pos->str(1));
}
for (auto temp : res)
ans = temp;
return QString::fromStdString(ans);
}
QString MainWindow::unicodeToUtf8(QString str) //unicode转utf8
{
QString result;
int index = str.indexOf("\\u");
qDebug()<<index;
//判断是否存在为转移字符,实践表明只有英文字母是可以正常显示不需要转码的
if(index!=-1){
/* 判断字符串是否全为转义字符,实践表明中文和韩文等全是转移
* 法语和德语只有个别特殊符号是转义字符
* */
if(index==0){
//全为转义
while (index != -1){
QString s1 = str.mid(index + 2, 4);
result.append(s1.toUShort(0, 16));
index = str.indexOf("\\u", index+5);
}
return result.toUtf8().constData();
}
else{
//部分转义
while (index != -1){
QString s1 = str.mid(index + 2, 4);
result=s1.toUShort(0, 16);
str.replace(index-1,7,result.toUtf8().constData());
index = str.indexOf("\\u", index+5);
}
return str;
}
}
return str;
// return result.toUtf8().constData();
}
MainWindow::~MainWindow()
{
delete ui;
}
最后还有启动的main函数
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
这样一个简易的翻译工具就做好了
补充:编码转码和一些报错处理
1.QtCreator默认的编码格式是utf-8
可以通过以下方式查看或修改
工具->选项,如下图
2.计算机会把utf-8或其他格式的数据转成Unicode,便于通信,这也是get请求返回的数据是Unicode格式的原因,所以在解析出dst字段后还要进行转码。
3.一下是我开发过程中遇到的一些问题,以及参考的一些优秀博主的解决方法
报错:No such slot
参考下面的解决方法
QT常见错误 | No such slot错误分析与解决
报错:
qt.network.ssl: QSslSocket::connectToHostEncrypted: TLS initialization failed
可以参考我的另一篇文章
https://blog.csdn.net/yyy90/article/details/113762890
总结一下
这是应该是我做的第一项目,我的c++作业是用VS2019+MFC做的,但是在编码格式这块没弄明白做的比较拉跨,而且比较麻烦不像Qt5有自带的访问网络的库,所以想用Qt5再做一次。
Qt小白,欢迎大家批评指正!