百度UNIT聊天API实现聊天对话

文章目录

    • 1.百度UNIT聊天API的使用
    • 2. QT中UI线程与工作线程的双向通信
      • 代码示例2
    • 3.UI

最终效果图:


[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-56EWw2Ki-1589776377292)(C:UsersAdministratorAppDataRoamingTyporatypora-user-imagesimage-20200518110659979.png)]

​ 图1.聊天情况

1.百度UNIT聊天API的使用

代码示例1

# -*- coding=utf-8 -*-
import requestsclass UNIT:def __init__(self, api_key, api_secret):self.access_token = Noneself.url = Noneself.set_access_token(api_key, api_secret)def set_access_token(self, api_key, api_secret):host = 'https://aip.baidubce.com/oauth/2.0/token?' 'grant_type=client_credentials&' 'client_id={0}&' 'client_secret={1}'.format(api_key, api_secret)response = requests.post(host)if response:self.access_token = response.json()['access_token']def query(self, query_text):self.url = 'https://aip.baidubce.com/rpc/2.0/unit/service/chat?access_token=' + self.access_tokenpost_data = """{"bot_session": "","log_id": "7758521","service_id": "S29640",	# 你的聊天机器人的ID"request": {"bernard_level": 1,"client_session": "{\"client_results\":\"\", \"candidate_options\": []}","query": "%s",	# 要查询的文字"query_info": {"asr_candidates": [],"source": "KEYBOARD","type": "TEXT"},"updates": "","user_id": "88888"},"session_id": "","version": "2.0"}""" % query_textpost_data = post_data.encode('utf-8')headers = {'content-type': 'application/x-www-form-urlencoded'}response = requests.post(self.url, data=post_data, headers=headers)if response:return response.json()['result']['response_list'][0]['action_list'][0]['say']

需要自己去百度UNIT获取自己的API_KEY和API_SECRET,然后调用set_access_token获取access_token来访问聊天API。

2. QT中UI线程与工作线程的双向通信

发现网上讲的基本都是工作线程向UI线程传递数据,却没有讲UI线程如何传递数据给工作线程。以下给出了一种思路。

代码示例2

UI线程点击按钮,向工作线程发送信息;工作线程处理好信息后通过信号传出。

# -*- coding=utf-8 -*-
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import pyqtSignal, pyqtSlot, QThreadclass WorkerThread(QThread):response_signal = pyqtSignal(str)	# 向UI线程发出的信号receive_string = None	# 用于接受来自UI线程的信息def __init__(self):super(WorkerThread, self).__init__()def run(self) -> None:# 处理UI线程传来的信息,然后发出信号self.response_signal[str].emit(self.receive_string + ",I got this")class MyWidget(QWidget):def __init__(self):super(MyWidget, self).__init__()self.button = QPushButton("send", self)self.button.clicked.connect(self.on_send_message)self.worker = WorkerThread()	# 实例化子线程self.worker.response_signal[str].connect(self.on_response)	# 绑定子线程的信号与UI线程的槽on_response@pyqtSlot()		# 据PYQT官网描述,加上装饰器可以减少内存消耗def on_send_message(self):self.worker.receive_string = "你好"	# 往子线程传递信息self.worker.start()		# 启动子线程@pyqtSlot(str)def on_response(self, text):print(text)if __name__ == "__main__":app = QApplication(sys.argv)window = MyWidget()window.show()sys.exit(app.exec_())

运行结果:

你好,I got this
你好,I got this
你好,I got this
你好,I got this

3.UI

部分个人觉得比较重要的实现:

聊天框使用QListWidget实现,每一条聊天内容使用QListWidgetItem实现。

聊天内容:图标+时间+消息。

def get_encapsulated_message(self):message_item = QListWidgetItem()	# 实例化一个QListWidgetItem对象time = QDateTime.currentDateTime().time().toString('hh:mm:ss')	# 获取当前时间message_item.setText(time + " " + self.input_text.text())	# 设置文本内容message_item.setIcon(QIcon('image/me.png'))	# 添加图标return message_item

有时候文本内容太长,需要设置自动换行:

self.chat_message_box.setWordWrap(True)                     # 开启长文本自动换行

chat_message_box是QListWidget类的对象。

在QListWidget中,每次内容都停留在顶部,无法自动下滑到最新的消息处:

self.chat_message_box.scrollToBottom()	# chat_message_box是QListWidget对象

在往QListWidget中添加QListWidgetItem后,调用QListWidget.scrollToBottom()即可。

Published by

风君子

独自遨游何稽首 揭天掀地慰生平