搭建界面
界面
运行后是这样的
因为我们要进行网络通信所以在.pro文件我们要加上network模块
代码
我们首先要根据deepseek的api的官方文档来参考
我们其实就是获取一段文字然后再发送出去 具体的格式是怎样的需要我们阅读官方文档
在右边有CURL我们根据这个来做参考
curl -L -X POST 'https://api.deepseek.com/chat/completions' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer 这里填写你自己的key' \
--data-raw '{
"messages": [
{
"content": "You are a helpful assistant",
"role": "system"
},
{
"content": "Hi",
"role": "user"
}
],
"model": "deepseek-chat",
"frequency_penalty": 0,
"max_tokens": 2048,
"presence_penalty": 0,
"response_format": {
"type": "text"
},
"stop": null,
"stream": false,
"stream_options": null,
"temperature": 1,
"top_p": 1,
"tools": null,
"tool_choice": "none",
"logprobs": false,
"top_logprobs": null
}'
首先我们要获取这个api Key
我们把上面的的位置替换成你自己的Key
还有一个就是stream这里要把false改成true stream就是流的意思 如果是false服务器可能一下子发送几千字要等好长时间 改成true就会实时发送
在这里有两个content和role 第一个是告诉服务器的 第一个role表示你是以老师的身份回答问题什么的
下面的content表示我们要说的话 我们只需要替换第二个content里的内容就可以
客户端代码
我们是在点击发送之后呢开始运行的 所以发送按钮我们之间点击转到槽
接下来我们要把我们刚刚复制的格式全部设置进去
//获取文本框内容
QString text=ui->inputEdit->toPlainText();
//发送请求对象
QNetworkRequest request;
request.setUrl(QUrl("https://api.deepseek.com/chat/completions"));
设置头
第一个头是本来就有的 第二三个头是自定义的
void MainWindow::on_pushButton_clicked()
{
//获取文本框内容
QString text=ui->inputEdit->toPlainText();
//发送请求对象
QNetworkRequest request;
request.setUrl(QUrl("https://api.deepseek.com/chat/completions"));
//设置固定头
request.setHeader(QNetworkRequest::ContentTypeHeader,"application/json");
//设置自定义的头
request.setRawHeader("Accept","application/json");
request.setRawHeader("Authorization","自己的密钥");
}
写json文件
我们首先写一个json数组
QJsonArray messages;
QJsonObject systemMsg;
systemMsg["role"]="system";
systemMsg["content"]="You are a helpful assistant";
QJsonObject userMsg;
userMsg["role"]="user";
userMsg["content"]=text;
messages.append(systemMsg);
messages.append(userMsg);
此时整个messages已经完成了 接下来我们还需要实现整个json对象
不用全部添加添加部分即可
QJsonObject requestBody;
requestBody["messages"]=messages;
requestBody["model"]="deepseek-chat";
requestBody["max_tokens"]=2048;
requestBody["stream"]=true;
requestBody["temperature"]=1;
发送请求
在mainwindow.h里添加一个网络管理者
在构造函数中初始化一下
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
manager=new QNetworkAccessManager();
}
通过这个对象进行发送请求 处理数据等
//发送请求
QNetworkReply *reply = manager->post(request,QJsonDocument(requestBody).toJson());
//处理数据
connect(reply,&QNetworkReply::readyRead,this,[=]{
qDebug()<<reply->readAll();
});
//接受结束了
connect(reply,&QNetworkReply::finished,this,[=](){
});
添加库文件
我们需要把ssleay32.dll和libeay.dll文件放入到debug文件中 这两个库文件在Qt/tool文件中可以搜索到
将 ssleay32.dll和 libeay32.dll放入 Debug 目录是为了确保 Qt 程序在调用 HTTPS 接口(如 AI API)时,能够找到 OpenSSL 库来完成安全通信。缺少这些 DLL 会导致 HTTPS 连接失败,程序无法正常调用 API。
析一下这个服务器回复的数据 我们读的时候肯会读到很多数据,我们采用每次读一行的方式 读到换行符就可 触发一次槽函数可能包含多条数据所以只要能读我们就一直读
这是简化后的 我们要提取delta的数据
//处理数据
connect(reply,&QNetworkReply::readyRead,this,[=]{
while(reply->canReadLine())
{
QString line=reply->readLine().trimmed();//trimmed可以去除开头和结尾的空格换行符等等
//我们要读的数据必须是data开头的数据
if(line.startsWith("data: "))
{
line.remove(0,6);//去除前面的data: 一共6个字节
QJsonParseError error;
QJsonDocument doc=QJsonDocument::fromJson(line.toUtf8(),&error);
if(error.error==QJsonParseError::NoError)//是个json对象
{
QString content=doc.object()["choices"].toArray().first()
.toObject()["delta"]
.toObject()["content"].toString();
if(!content.isEmpty())
{
ui->outputEdit->moveCursor(QTextCursor::End);
ui->outputEdit->insertPlainText(content);
}
}
}
}
});
读到最后碰到[DONE]代表结束
//接受结束了
connect(reply,&QNetworkReply::finished,this,[=](){
ui->outputEdit->moveCursor(QTextCursor::End);
ui->outputEdit->insertPlainText("\n\n\n\n");
reply->deleteLater();
});
实现记忆化回复
// 当网络请求完成时,连接回复完成的信号到处理槽函数
connect(reply, &QNetworkReply::finished, this, [=] {
// ==== 获取AI回复内容 ====
// 获取输出文本框中的完整对话历史
QString fullText = ui->outputEdit->toPlainText();
// ==== 定位对话分割位置 ====
// 查找最后一次用户输入标记的位置(格式:-->用户输入内容)
int lastUserInputPos = fullText.lastIndexOf("-->" + text); // text应为用户最后输入内容
// ==== 提取AI回复 ====
// 从用户输入结束位置开始截取AI回复内容:
// 1. 起始位置 = 用户输入位置 + 用户输入文本长度 + 2("> "分隔符长度)
// 2. 使用trimmed()去除首尾空白字符
QString aiReply = fullText.mid(lastUserInputPos + text.length() + 2).trimmed();
// ==== 保存到对话历史 ====
if (!aiReply.isEmpty()) {
QJsonObject aiMsg;
aiMsg["role"] = "assistant"; // 标识消息角色为AI助手
aiMsg["content"] = aiReply; // 存储AI回复内容
conversationHistory.append(aiMsg); // 将消息对象添加到对话历史数组
}
// ==== UI界面更新 ====
ui->outputEdit->moveCursor(QTextCursor::End); // 移动光标到文本框末尾
ui->outputEdit->insertPlainText("\n\n\n\n"); // 插入换行分隔对话段落
// ==== 资源清理 ====
reply->deleteLater(); // 安全释放网络回复对象
});