200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > Qt通讯录(语音输入+发邮件+发短信+头像)

Qt通讯录(语音输入+发邮件+发短信+头像)

时间:2024-01-11 21:15:15

相关推荐

Qt通讯录(语音输入+发邮件+发短信+头像)

Qt通讯录(语音输入+发邮件+发短信+头像)

项目背景功能运行程序关键技术语音识别ASR发送电子邮件AddressBook5.0Gitee地址

项目背景

作为一个Qt小白,迫于大一下学期的C++大作业的需要,我看了两天的黑马程序员Qt视频教程,学有小成,便操刀上阵了。捣鼓了一个星期,写了3000多行代码,终于实现得差不多了。期间历程坎坷,感受颇多,因此在这里写下我的第一篇博客。

功能

1.新建/编辑/删除联系人;

2.按姓名/出生日期对联系人进行排序;

3.按照关键字来查找联系人;

4.给联系人打电话(形式上);

5.语音识别输入;

6.给联系人发邮件并自动生成贺信;

7.修改登录密码或其他用户信息;

8.登录账号密码保护和账号注销。

运行程序

bilibili网址

Qt个人通讯录介绍

关键技术

由于代码比较多且复杂,我就不一一贴出来,下面展示关键技术,代码下载链接在文末。

语音识别ASR

asr.h

//功能:启动录音设备,对数据编码上传网络,调用百度语音识别ASR,获取识别文本#ifndef ASR_H#define ASR_H#include <QMainWindow>#include <QtNetwork>#include <QJsonDocument>#include <QJsonParseError>#include <QDebug>#include<QAudioInput>#include<QMediaPlayer>#include<QMessageBox>#include<QTime>#include<QSettings>#include<QKeyEvent>#include<QString>#include<QUrl>class ASR : public QMainWindow{Q_OBJECTpublic:int isStop=1;//填写API_KEY和Secret_Keyconst QString API_KEY="";const QString Secret_Key="";QString Access_Token="";//vedio to textconst QString VOP_URL="/server_api";//Text to vedioconst QString TSN_URL="/text2audio";QString Get_Token_URL="/oauth/2.0/token";QString MAC_cuid="";//语音识别的结果QString voice_get_ans;explicit ASR(QWidget *parent = 0);~ASR();QAudioDeviceInfo SpeechCurrentDevice;QAudioInput* audio_input=NULL;QBuffer* JsonBuffer=NULL;void AudioInit();void TokenInit();void getMacAddress();//更改voice_get_ansvoid changeBaiduAudioAns(QString str);bool JudgeTokenTime();void startASR();void stopASR();signals:void outputASR(QString ASRtext);public slots://识别声音获得文字void Baidu_VoiceToText_replyFinish(QNetworkReply* reply);void get_Token_slot(QNetworkReply* reply);};#endif // ASR_H

asr.cpp

#include "asr.h"ASR::ASR(QWidget *parent) :QMainWindow(parent){AudioInit();getMacAddress();TokenInit();}//录音设备初始化void ASR::AudioInit(){const auto &&availableDevices = QAudioDeviceInfo::availableDevices(QAudio::AudioInput);if(!availableDevices.isEmpty()){SpeechCurrentDevice = availableDevices.first();QAudioFormat format;format.setSampleRate(8000);format.setChannelCount(1);format.setSampleSize(16);format.setSampleType(QAudioFormat::SignedInt);format.setByteOrder(QAudioFormat::LittleEndian);format.setCodec("audio/pcm");audio_input = new QAudioInput(SpeechCurrentDevice, format, this);}}//百度语音识别令牌初始化void ASR::TokenInit(){if(JudgeTokenTime()) return;QUrl url=QUrl(Get_Token_URL+"?grant_type=client_credentials"+"&client_id="+API_KEY+"&client_secret="+Secret_Key);QNetworkAccessManager *manager=new QNetworkAccessManager(this);QNetworkRequest request(url);connect(manager,SIGNAL(finished(QNetworkReply *)),this,SLOT(get_Token_slot(QNetworkReply *)));manager->get(request);}//若成功得到令牌则响应void ASR::get_Token_slot(QNetworkReply *reply){QByteArray JsonStr=reply->readAll();QJsonObject acceptedData(QJsonDocument::fromJson(JsonStr).object());if(acceptedData.contains("access_token")){QJsonValue json_value = acceptedData.take("access_token");Access_Token=json_value.toString();qDebug()<<"success get token:"<<Access_Token;}}ASR::~ASR(){}//更改voice_get_ans值的函数,用于发射信号void ASR::changeBaiduAudioAns(QString str){//去掉末尾的句号并更新voice_get_ansthis->voice_get_ans=str.remove(str.length()-1,1);qDebug()<<"识别声音结果 "<<this->voice_get_ans;//发射信号告知已成功识别语音,并传递文本voice_get_ansemit this->outputASR(voice_get_ans);}//判断令牌是否失效,每次生成的令牌使用期为一个月,过期后需再次申请bool ASR::JudgeTokenTime(){QSettings *setting=new QSettings("GetTokenTime.ini",QSettings::IniFormat);//当前时间QDateTime current_date_time=QDateTime::currentDateTime();QDateTime file_date_time;//读取的文件时间QString file_date_str=setting->value("/TIME/last_time").toString();file_date_time=QDateTime::fromString(file_date_str,"yyyy-MM-dd");// qDebug()<<"file_date_time"<<file_date_time;uint stime = file_date_time.toTime_t();uint etime = current_date_time.toTime_t();int ndaysec = 24*60*60;int Day= (etime - stime)/(ndaysec) + ((etime - stime)%(ndaysec)+(ndaysec-1))/(ndaysec) - 1;//Token 有效期内if(Day<30) return true;else{//写时间setting->beginGroup("TIME");setting->setValue("last_time",current_date_time.toString("yyyy-MM-dd"));setting->endGroup();return false;}}//获取本机MAC地址void ASR::getMacAddress(){QList<QNetworkInterface> nets = QNetworkInterface::allInterfaces();// 获取所有网络接口列表int nCnt = nets.count();for(int i = 0; i < nCnt; i ++){// 如果此网络接口被激活并且正在运行并且不是回环地址,则就是我们需要找的Mac地址if(nets[i].flags().testFlag(QNetworkInterface::IsUp) && nets[i].flags().testFlag(QNetworkInterface::IsRunning) && !nets[i].flags().testFlag(QNetworkInterface::IsLoopBack)){MAC_cuid = nets[i].hardwareAddress();break;}}MAC_cuid.replace(":","-");qDebug()<<"自动获取的MAC地址 "<<MAC_cuid;}//声音转成文本void ASR::Baidu_VoiceToText_replyFinish(QNetworkReply *reply){qDebug()<<"进到槽函数了";QByteArray JsonStr=reply->readAll();qDebug()<<"返回信息 "<<JsonStr;QJsonObject acceptedData(QJsonDocument::fromJson(JsonStr).object());if(acceptedData.contains("err_no")){QJsonValue version_value = acceptedData.take("err_no");if(version_value.isDouble()){int version = version_value.toVariant().toInt();if(version == 3300){//textEdit -> append("错误代码:3300-输入参数不正确,请仔细核对文档及参照demo,核对输入参数");//重新写入文本}else if(version == 3301){//textEdit -> append("错误代码:3301-音频质量过差,请上传清晰的音频");//重新写入文本QMessageBox::information(NULL,tr("识别失败"),tr("请等待一秒后开始录音,确认录音质量良好"));}else if(version == 3302){//textEdit -> append("错误代码:3302-鉴权失败,token字段校验失败。请用appkey 和 app secret生成");//重新写入文本}else if(version == 3303){//textEdit -> append("错误代码:3303-转pcm失败,如下2个原因 1. wav amr音频转码失败,即音频有问题。2. 服务端问题,请将api返回结果反馈至论坛或者QQ群");//重新写入文本}else if(version == 3304){//textEdit -> append("错误代码:3304-用户的请求QPS超限,请降低识别api请求频率 (qps以appId计算,移动端如果共用则累计)");//重新写入文本}else if(version == 3305){//textEdit -> append("错误代码:3305-用户的日pv(日请求量)超限,请“申请提高配额”,如果暂未通过,请降低日请求量");//重新写入文本}else if(version == 3307){//textEdit -> append("错误代码:3307-语音服务器后端识别出错问题,请将api返回结果反馈至论坛或者QQ群");//重新写入文本}else if(version == 3308){//textEdit -> append("错误代码:3308-音频过长,音频时长不超过60s,请将音频时长截取为60s以下");//重新写入文本}else if(version == 3309){//textEdit -> append("错误代码:3309-音频数据问题,服务端无法将音频转为pcm格式,可能是长度问题,音频格式问题等。 请将输入的音频时长截取为60s以下,并核对下音频的编码,是否是8K或者16K, 16bits,单声道。");//重新写入文本}else if(version == 3310){//textEdit -> append("错误代码:3310-输入的音频文件过大,语音文件共有3种输入方式: json 里的speech 参数(base64后); 直接post 二进制数据,及callback参数里url。 分别对应三种情况:json超过10M;直接post的语音文件超过10M;callback里回调url的音频文件超过10M");//重新写入文本}else if(version == 3311){//textEdit -> append("错误代码:3311-采样率rate参数不在选项里,目前rate参数仅提供8000,16000两种,填写4000即会有此错误");//重新写入文本}else if(version == 3312){//textEdit -> append("错误代码:3312-音频格式format参数不在选项里,目前格式仅仅支持pcm,wav或amr,如填写mp3即会有此错误");//重新写入文本}// return;}}if(!acceptedData["result"].isNull()){QString message=acceptedData["result"].toArray()[0].toString();qDebug()<<message;changeBaiduAudioAns(message);}}//开始语音识别void ASR::startASR(){JsonBuffer=new QBuffer;JsonBuffer->open(QIODevice::ReadWrite);qDebug()<<"录音设备访问成功...";audio_input->start(JsonBuffer);qDebug()<<"录音设备运行成功...";isStop=0;}//结束语音识别void ASR::stopASR(){qDebug()<<"结束录音";audio_input->stop();const auto &sendData=JsonBuffer->data();JsonBuffer->deleteLater();//必须加thisQNetworkRequest request(QUrl(this->VOP_URL));request.setRawHeader("Content-Type", "application/json");qDebug()<<"jason_speech:request设置头成功 ...";QNetworkAccessManager *manager=new QNetworkAccessManager(this);connect(manager,SIGNAL(finished(QNetworkReply *)),this,SLOT(Baidu_VoiceToText_replyFinish(QNetworkReply *)));//这里应该放在百度类里面QJsonObject append;//设置json请求格式append["format"] = "pcm";append["rate"] = 8000;append["channel"] = 1;append["token"] = Access_Token;append["lan"] = "zh";append["cuid"] = MAC_cuid;append["speech"] = QString(sendData.toBase64());append["len"] = sendData.size();//发送HTTP post请求manager->post(request,QJsonDocument(append).toJson());isStop=1;}

调用方式

//在mainwindow.h中声明一个ASR对象ASR *asrMainWindow=new ASR;//在mainwindow.cpp中提供键盘按键事件函数,F2:语音输入void MainWindow::keyPressEvent(QKeyEvent *event){if(event->key()==Qt::Key_F2){if(asrMainWindow->isStop==1){asrMainWindow->startASR();}else{asrMainWindow->stopASR();}}}//信号和槽connect(asrMainWindow,&ASR::outputASR,[=](QString ASRtext){qDebug()<<ASRtext;});

发送电子邮件

发送电子邮件的功能由sendemail文件夹里的28个文件实现。

调用方法

这里实现的是163和qq邮箱的发送,其它大部分邮箱同样也能实现

//功能:其UI文件显示发送邮件界面,并显示进度条,用户在进度条达到100%之前可以取消发送邮件,否则会弹出邮箱SMTP服务授权码输入窗口,若授权码正确即可发送邮件//核心代码为sendmail包,可实现发邮件功能(简单文本,富文本,附件,图片等),也可以群发邮件//判断发件人邮箱为那种类型的邮箱//若为163邮箱则设置服务器为,端口为25,通讯协议为TcpConnection;若为qq邮箱则设置服务器为,端口为465,通讯协议为SslConnection;//由于此应用为通讯录管理系统,所以我只是用它实现了发送简单文本给一位联系人的功能。//发送成功后会显示当前邮件的发送时间yyyy.mm.dd H:M:S dddd年月日 时分秒 星期几//需输入邮箱SMTP服务授权码(不是邮箱密码),方能在第三方客户端发送邮件//开通QQ邮箱的SMTP服务教程:/article/5225f26b017159e6fa0908ff.html//实例化发送邮件对象SmtpClient smtp("",25,SmtpClient::TcpConnection);if(senderEmail.contains("@")){qDebug()<<"邮件类型1";}if(senderEmail.contains("@")){qDebug()<<"邮件类型2";smtp.host="";smtp.port=465;smtp.setConnectionType(SmtpClient::SslConnection);}smtp.setUser(senderEmail);QFile file("EmailPassword.txt");file.open(QFile::ReadOnly);QString str=file.readLine();file.close();smtp.setPassword(str);//构建邮件主题,包含发件人收件人附件等.MimeMessage message;message.setSender(new EmailAddress(senderEmail));//逐个添加收件人message.addRecipient(new EmailAddress(receiverEmail));//构建邮件标题message.setSubject(QStringLiteral("你的一位联系人发来的信息"));//构建邮件正文MimeText text;text.setText(emailMessage);message.addPart(&text);if (!smtp.connectToHost()){ui->label_2->setText("发送失败");QMessageBox::critical(this,"错误","服务器连接失败!");return;}if (!smtp.login()){ui->label_2->setText("发送失败");QMessageBox::critical(this,"错误","用户登录失败!");return;}if (!smtp.sendMail(message)){ui->label_2->setText("发送失败");QMessageBox::critical(this,"错误","邮件发送失败!");return;}else{QMessageBox::information(this,"提示","邮件发送成功!");}smtp.quit();

其它调用方法

//粗略步骤://第一步:布局好界面,控件命名好,建议用pascal命名法。//第二步:准备好sendemailapi文件夹,里面存放的公开的第三方的支持发送附件和富文本的MIME协议文件。添加到项目中。//第三步:实例化邮件发送对象SmtpClient smtp(ui->cboxServer->currentText(),ui->cboxPort->currentText().toInt(),ui->ckSSL->isChecked()?SmtpClient::SslConnection:SmtpClient::TcpConnection);smtp.setUser(ui->txtSender->text());smtp.setPassword(ui->txtSenderPwd->text());//第四步:构建邮件主题,包含发件人收件人附件等MimeMessage message;message.setSender(new EmailAddress(ui->txtSenderAddr->text()));//逐个添加收件人QStringList receiver = ui->txtReceiverAddr->text().split(';');for (int i = 0; i < receiver.size(); i++){message.addRecipient(new EmailAddress(receiver.at(i)));}//构建邮件标题message.setSubject(ui->txtTitle->text());//构建邮件正文MimeHtml text;text.setHtml(ui->txtContent->toHtml());// //如果直接发送简单文本,使用以下方法// MimeText text;// text.setText("测试简单文本发送!");message.addPart(&text);//构建附件QString atta=ui->txtAtta->text();if (atta!=""){QStringList attas=atta.split(";");foreach (QString tempAtta, attas) {QFile *file=new QFile(tempAtta);if (file->exists()){message.addPart(new MimeAttachment(file));}}}//第五步:登录服务器发送邮件if (!smtp.connectToHost()){QMessageBox::critical(this,"错误","服务器连接失败!");return;}if (!smtp.login()){QMessageBox::critical(this,"错误","用户登录失败!");return;}if (!smtp.sendMail(message)){QMessageBox::critical(this,"错误","邮件发送失败!");return;}else{QMessageBox::information(this,"错误","邮件发送成功!");}smtp.quit();

AddressBook5.0

更新时间:.7.12

新增加了发短信和设置头像的功能,并更改为英文版软件。

软件展示视频地址:/video/BV1Ct4y1U7jw/

Gitee地址

-1-25 09:40:27 Gitee地址

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。