如何在Qt项目中加入一个聊天机器人并采用tts技术使他”说话”?
api选择
选择国产图灵机器人,其接口:http://www.tuling123.com/api/product_exper/chat.jhtml
,这是一个post
请求接口,在后缀需加上?info=你要说的内容
,返回的是一个xml格式的数据。需要相应格式解析,在.pro
配置文件中加入QT += network xml
。选择QTableView
作为展示聊天记录的窗口,QStandardItemModel
作为数据模型。
在头文件中引入网络模块
1 2 3 4 5 6 7 8 9 10
|
class QTextToSpeech; private: QNetworkAccessManager *manage; QStandardItemModel *session; int rawCount; QTextToSpeech *tts;
|
在cpp文件构造函数中初始化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
ui->btn_send->setEnabled(false); //发送按钮 connect(ui->textEdit_send,SIGNAL(textChanged()),this,SLOT(enableSendBtn())); session = new QStandardItemModel(this); // 自动延伸填满整个宽度 ui->tableView_session->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); // 背景色交替 ui->tableView_session->setAlternatingRowColors(true); ui->tableView_session->setStyleSheet("QTableView::item {alternate-background-color: #f3f4f5;}"); // 设置选中行背景色 ui->tableView_session->setStyleSheet("QTableView::item:selected {background-color: #F8F0DD;color: #3a3a3a;}"); //设置不显示格子线 ui->tableView_session->setShowGrid(false); ui->tableView_session->setWordWrap(false); ui->tableView_session->setModel(session); rawCount =0; // 记录聊天量 tts = new QTextToSpeech(this); tts->setLocale(QLocale::Chinese);
|
初始化进度管理
1 2 3 4
| void chatRobot::Init(){ manage = new QNetworkAccessManager(this); connect(manage, SIGNAL(finished(QNetworkReply*)), this, SLOT(readReply(QNetworkReply*))); }
|
发送按钮只有在发送内容不为空才为真
1 2 3 4 5 6 7
| void chatRobot::enableSendBtn(){ if(!ui->textEdit_send->toPlainText().isEmpty()){ ui->btn_send->setEnabled(true); }else{ ui->btn_send->setEnabled(false); } }
|
发送请求
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| void chatRobot::on_btn_send_clicked(){ // 接入图灵机器人聊天接口 QString RobotUrl = "http://www.tuling123.com/api/product_exper/chat.jhtml"; QNetworkRequest req; QString word = ui->textEdit_send->toPlainText(); session->setItem(rawCount++, new QStandardItem(QIcon(":/images/me"), word)); // 根据内容自动调整行高 ui->tableView_session->resizeRowToContents(rawCount-1); QUrl baseUrl(RobotUrl); QUrlQuery query; query.addQueryItem("info", word); baseUrl.setQuery(query); //以后缀形式加在url后 req.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); req.setUrl(QUrl(baseUrl)); manage->post(req, ""); ui->btn_send->setEnabled(false); // 防止一条信息因错按发送按钮多次发送 }
|
接受服务器返回数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| void chatRobot::readReply(QNetworkReply* reply){ QByteArray ans = reply->readAll(); QString strAns; strAns.prepend(ans);// QByteArray转QString方法2 QString content; QDomDocument doc; int code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); if(code == 200){ doc.setContent(strAns); QDomElement root = doc.documentElement(); //返回根节点 QDomNode node = root.firstChild(); //获得第一个子节点 while(!node.isNull()){ //如果节点不空 if(node.isElement()){ //如果节点是元素 QDomElement element=node.toElement(); //转换为元素 if(element.tagName() == "Content"){ content = element.text(); break; } } node=node.nextSibling(); //下一个兄弟节点 } session->setItem(rawCount++, new QStandardItem(QIcon(":/images/robot"), content)); ui->tableView_session->resizeRowToContents(rawCount-1); // 文本转语音 tts->stop(); tts->say(content); // 播放 }else{ QMessageBox::warning(this,tr("warning"), tr("Network Error, HttpStatusCode: %1").arg(code),QMessageBox::Ok); } ui->btn_send->setEnabled(true); }
|
大概运行效果如下