基于 PyQt5 的聊天机器人程序(AI)

news2025/2/23 9:41:17

       这是一个基于 PyQt5 的聊天机器人程序,通过 API 接入硅基流动(Silicon Flow)或其他的聊天服务,支持用户与聊天机器人进行交互。

  • API 设置:通过菜单栏的“设置”选项,用户可以修改 API 地址和 API 密钥。
  • 设置对话框:提供输入框用于修改 API 地址和 API 密钥。

 核心功能

  • 发送消息:用户输入消息后,点击“发送”按钮或按回车键发送消息。
  • 获取回复:通过 API 请求获取聊天机器人的回复。
  • 显示对话:将用户消息和机器人回复显示在聊天记录区域。

API 集成

  • API 地址:默认使用 https://api.siliconflow.com/v1/chat,支持通过设置对话框修改。
  • API 密钥:需要提供有效的 API 密钥,支持通过设置对话框修改。
  • 请求参数:包括用户消息、温度(temperature)和最大 token 数(max_tokens)。

交互流程

  • 用户启动程序,界面显示聊天记录区域、输入框和发送按钮。
  • 用户在输入框中输入消息,点击“发送”按钮或按回车键。
  • 程序通过 API 请求获取聊天机器人的回复。
  • 将用户消息和机器人回复显示在聊天记录区域。
import sys
import requests
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, 
                            QHBoxLayout, QPushButton, QTextEdit, QLabel, QLineEdit,
                            QDialog, QFormLayout, QDialogButtonBox)
from PyQt5.QtCore import Qt

class SettingsDialog(QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle("API 设置")
        
        # 创建表单布局
        layout = QFormLayout(self)
        
        # API 地址输入框
        self.api_url_input = QLineEdit(self)
        layout.addRow("API 地址:", self.api_url_input)
        
        # API 密钥输入框
        self.api_key_input = QLineEdit(self)
        self.api_key_input.setEchoMode(QLineEdit.Password)
        layout.addRow("API 密钥:", self.api_key_input)
        
        # 按钮
        buttons = QDialogButtonBox(
            QDialogButtonBox.Ok | QDialogButtonBox.Cancel,
            Qt.Horizontal, self)
        buttons.accepted.connect(self.accept)
        buttons.rejected.connect(self.reject)
        layout.addRow(buttons)
        
    def get_settings(self):
        """获取用户输入的设置"""
        return {
            'api_url': self.api_url_input.text().strip(),
            'api_key': self.api_key_input.text().strip()
        }

class ChatBotUI(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("硅基流动聊天机器人")
        self.setGeometry(100, 100, 800, 600)
        
        # 初始化UI
        self.init_ui()
        
        # 初始化 API 设置
        self.api_url = "https://api.siliconflow.com/v1/chat"
        self.api_key = "sk-gt**********mux"  #请输入你的API秘钥
        
    def init_ui(self):
        """初始化用户界面"""
        # 创建主窗口部件和布局
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        layout = QVBoxLayout(central_widget)
        
        # 创建菜单栏
        self.create_menu_bar()
        
        # 创建聊天记录显示区域
        self.chat_display = QTextEdit()
        self.chat_display.setReadOnly(True)
        self.chat_display.setStyleSheet("""
            QTextEdit {
                font-size: 14px;
                margin: 10px;
                padding: 10px;
                background-color: #f0f0f0;
                border-radius: 5px;
            }
        """)
        layout.addWidget(self.chat_display)
        
        # 创建输入区域
        input_layout = QHBoxLayout()
        
        # 用户输入框
        self.user_input = QLineEdit()
        self.user_input.setPlaceholderText("请输入您的问题...")
        self.user_input.returnPressed.connect(self.send_message)
        input_layout.addWidget(self.user_input)
        
        # 发送按钮
        self.btn_send = QPushButton("发送")
        self.btn_send.clicked.connect(self.send_message)
        input_layout.addWidget(self.btn_send)
        
        layout.addLayout(input_layout)
        
        # 状态栏
        self.status_label = QLabel("准备就绪")
        self.status_label.setAlignment(Qt.AlignCenter)
        self.status_label.setStyleSheet("""
            QLabel {
                font-size: 12px;
                color: #666;
                margin: 5px;
            }
        """)
        layout.addWidget(self.status_label)
        
    def create_menu_bar(self):
        """创建菜单栏"""
        menubar = self.menuBar()
        
        # 添加设置菜单
        settings_menu = menubar.addMenu('设置')
        
        # 添加 API 设置选项
        api_settings_action = settings_menu.addAction('API 设置')
        api_settings_action.triggered.connect(self.show_api_settings)
        
    def show_api_settings(self):
        """显示 API 设置对话框"""
        dialog = SettingsDialog(self)
        if dialog.exec_():
            settings = dialog.get_settings()
            self.api_url = settings['api_url']
            self.api_key = settings['api_key']
            self.status_label.setText("API 设置已更新")
            
    def send_message(self):
        """发送消息并获取回复"""
        user_message = self.user_input.text().strip()
        if not user_message:
            return
            
        # 显示用户消息
        self.append_message("用户", user_message)
        self.user_input.clear()
        
        # 获取机器人回复
        self.status_label.setText("正在获取回复...")
        try:
            response = self.get_bot_response(user_message)
            self.append_message("机器人", response)
            self.status_label.setText("回复已接收")
        except Exception as e:
            self.append_message("系统", f"错误: {str(e)}")
            self.status_label.setText("获取回复时出错")
            
    def get_bot_response(self, message):
        """调用 API 获取机器人回复"""
        headers = {
            "Authorization": f"Bearer {self.api_key}",
            "Content-Type": "application/json"
        }
        
        data = {
            "message": message,
            "temperature": 0.7,
            "max_tokens": 100
        }
        
        try:
            response = requests.post(self.api_url, json=data, headers=headers)
            response.raise_for_status()
            
            # 打印原始响应内容用于调试
            print("API 响应内容:", response.text)
            
            # 尝试解析 JSON
            json_response = response.json()
            return json_response["choices"][0]["message"]["content"]
            
        except requests.exceptions.RequestException as e:
            print(f"API 请求错误: {str(e)}")
            raise Exception(f"API 请求失败: {str(e)}")
        except ValueError as e:
            print(f"JSON 解析错误: {str(e)}")
            print("原始响应内容:", response.text)
            raise Exception("API 返回了无效的 JSON 数据")
        except KeyError as e:
            print(f"响应格式错误: {str(e)}")
            print("完整响应:", json_response)
            raise Exception("API 返回了意外的响应格式")
        
    def append_message(self, sender, message):
        """在聊天记录中添加消息"""
        self.chat_display.append(f"<b>{sender}:</b> {message}")
        self.chat_display.ensureCursorVisible()
        
def main():
    app = QApplication(sys.argv)
    window = ChatBotUI()
    window.show()
    sys.exit(app.exec_())

if __name__ == "__main__":
    main() 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2303857.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[实现Rpc] 服务端 | RpcRouter实现 | Builder模式

目录 项目服务端独用类的实现 1. RpcRouter类的实现 ServiceDescribe SDescribeFactory ⭕ Builder模式 1. 动机 2. 模式定义 3. 要点总结 4. 代码感受 ServiceManager RpcRouter 4. 代码感受 ServiceManager RpcRouter 前文我们就将 Rpc 通用类都实现完啦&#…

红外人体传感器选型和电路解析

红外人体传感器选型和电路解析 背景&#xff1a;想要制作一套IoT系统&#xff0c;基于HA构建上层管理&#xff0c;蓝牙和蓝牙MESH构建无线网络&#xff0c;以及多种传感器和控制器作为底层&#xff0c;其中人体红外传感器作为一个重要的选项&#xff0c;需要考虑好。 红外人体传…

rtthread的串口框架、485框架

一、串口接收超时中断的实现。 1. rtthread中定义的串口超时结构体 定义串口接收超时的结构体 CM_TMR0_TypeDef 为TM0的实例(实际有CM_TMR0_1 CM_TMR0_2 对应华大460的两个TMR0单元 ) channel 每个timer0有两个通道(TMR0_CHA、TMR0_CHB) clock 为FCG2_PERIPH_TMR0_1、FCG…

Embedding模型

检索的方式有那些 关键字搜索&#xff1a;通过用户输入的关键字来查找文本数据。 语义搜索&#xff1a;它的目标是理解用户查询的真实意图&#xff0c;不仅考虑关键词的匹配&#xff0c;还考虑词汇之间的语义 &#xff08;文字&#xff0c;语音&#xff0c;语调...&#xff0…

最新扣子(Coze)案例教程:全自动DeepSeek 写影评+批量生成 + 发布飞书,提效10 倍!手把手教学,完全免费教程

&#x1f468;‍&#x1f4bb;群里有同学是做影视赛道的博主&#xff0c;听说最近DeepSeek这么火&#xff0c;咨询能不能用DeepSeek写影评&#xff0c;并整理电影数据资料&#xff0c;自动发布到飞书文档&#xff0c;把每天的工作做成一个自动化的流程。 那今天斜杠君就为大家…

Ubuntu 22.04安装K8S集群

以下是Ubuntu 22.04安装Kubernetes集群的步骤概要 一、设置主机名与hosts解析 # Master节点执行 sudo hostnamectl set-hostname "k8smaster" # Worker节点执行 sudo hostnamectl set-hostname "k8sworker1"# 所有节点的/etc/hosts中添加&#xff1a; ca…

Apifox 增强 AI 接口调试功能:自动合并 SSE 响应、展示DeepSeek思考过程

在现代的API接口调试中&#xff0c;效率和精确性对于开发者和测试人员来说至关重要。Apifox&#xff0c;作为一款功能强大的API管理和调试工具&#xff0c;近年来不断提升其用户体验和智能化功能。最近&#xff0c;Apifox 推出了增强版的AI接口调试功能&#xff0c;其中包括自动…

MATLAB基础学习相关知识

MATLAB安装参考&#xff1a;抖音-记录美好生活 MATLAB基础知识学习参考&#xff1a;【1小时Matlab速成教程-哔哩哔哩】 https://b23.tv/CnvHtO3 第1部分&#xff1a;变量定义和基本运算 生成矩阵&#xff1a; % 生成矩阵% 直接法% ,表示行 ;表示列 a [1,2,3;4,5,6;7,8,9];%…

DeepSeek赋能智慧文旅:新一代解决方案,重构文旅发展的底层逻辑

DeepSeek作为一款前沿的人工智能大模型&#xff0c;凭借其强大的多模态理解、知识推理和内容生成能力&#xff0c;正在重构文旅产业的发展逻辑&#xff0c;推动行业从传统的经验驱动向数据驱动、从人力密集型向智能协同型转变。 一、智能服务重构&#xff1a;打造全域感知的智…

蓝桥与力扣刷题(蓝桥 交换瓶子)

题目&#xff1a;有 N 个瓶子&#xff0c;编号 1 ~ N&#xff0c;放在架子上。 比如有 5 个瓶子&#xff1a; 2 1 3 5 4 要求每次拿起 2 个瓶子&#xff0c;交换它们的位置。 经过若干次后&#xff0c;使得瓶子的序号为&#xff1a; 1 2 3 4 5 对于这么简单的情况&#x…

腿足机器人之十一- 深度强化学习

腿足机器人之十一- 深度强化学习 机器人能力腿足机器人RL问题建模强化学习解决方案 强化学习算法库选择建议 深度学习技术已经在语音、图像、视频、文本等领域应用广泛&#xff0c;其和强化学习的结合使得基于深度学习的大模型能力更是上升一个台阶。因而用在腿足机器人的运动中…

纠错检索增广生成论文

一、摘要 动机&#xff1a;RAG严重依赖于检索文档的相关性&#xff0c;如果检索出错&#xff0c;那么LLM的输出结果也会出现问题 解决方案&#xff1a;提出纠正性检索增强生成&#xff08;CRAG&#xff09;即设计一个轻量级的检索评估器&#xff0c;用来评估针对某个查询检索…

多源 BFS 算法详解:从原理到实现,高效解决多源最短路问题

多源 BFS 是一种解决 边权为 1 的多源最短路问题 的高效算法。其核心思想是将所有源点视为一个“超级源点”&#xff0c;通过一次 BFS 遍历即可计算所有节点到最近源点的最短距离。以下从原理、实现和代码示例三个方面深入讲解&#xff1a; 目录 一、原理分析 1. 单源 BFS vs…

Jenkins 构建 Unity 打包 .apk 同时生成 .aab

Jenkins 构建 Unity 打包 .apk 同时生成 .aab Android App Bundle简称 AAB&#xff0c;想了解更多关于 AAB 的知识&#xff0c;请看官网 https://developer.android.google.cn/guide/app-bundle/faq?hlzh-cn APK 打包部分在复用上一篇 Jenkins 构建 Unity打包APK 一、新建一…

清华大学第五弹:《DeepSeek与AI幻觉》

作者&#xff1a;清华大学新闻与传播学院新媒体研究中心、人工智能学院&#xff08;新媒沈阳团队&#xff09; 时间&#xff1a;2025年2月 完整版下载地址&#xff1a;夸克网盘分享 一、AI幻觉的定义与分类 定义 学术定义&#xff1a;模型生成与事实不符、逻辑断裂或脱离上下…

分布式数据库解析

title: 分布式数据库解析 date: 2025/2/20 updated: 2025/2/20 author: cmdragon excerpt: 通过金融交易、社交平台、物联网等9大真实场景,结合Google Spanner跨洲事务、DynamoDB毫秒级扩展等38个生产级案例,揭示分布式数据库的核心原理与工程实践。内容涵盖CAP定理的动态…

Zotero 快速参考文献导出(特定期刊引用)

目录 一、添加样式 每次投期刊时每种期刊的引用方式不一样&#xff0c;就很麻烦。发现zeotero添加期刊模板再导入很方便 一、添加样式 然后就能导出自己想要的期刊格式的引用了

库的制作与原理(一)

1.库的概念 库是写好的&#xff0c;现成的可以复用的代码。本质上库是一种可执行的二进制形式&#xff0c;可以被操作系统载入内存执行。库有俩种&#xff1a;静态库 .a[Linux] .lib[windows] 动态库 .so[Linux] .dll[windows] 就是把.c文件变成.o文件&#xff0c;把…

go 日志框架

内置log import ("log""os" )func main() {// 设置loglog.SetFlags(log.Llongfile | log.Lmicroseconds | log.Ldate)// 自定义日志前缀log.SetPrefix("[pprof]")log.Println("main ..")// 如果用format就用PrintF&#xff0c;而不是…

Rust配置笔记

1.Node.js下载配置 2.c环境配置 C我是用vs装的点击这个installer 点击修改 选择C环境就行,这个时候它就帮忙配置环境了 3.Rust下载配置 4.装napi-rs框架 npm install -g napi-rs/cliRust下载网站 下完之后直接打开 一开始下包会比较慢,多等等 下好之后跑项目前第一件事配置…