文章目录
-
- 1.百度UNIT聊天API的使用
- 2. QT中UI线程与工作线程的双向通信
-
- 代码示例2
- 3.UI
图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()即可。