Python使用PyQt5实现与DeepSeek聊天的图形化小软件

 更新时间:2025年03月11日 10:35:55   作者:老胖闲聊  
在 PyQt5 中,菜单栏(QMenuBar)、工具栏(QToolBar)和状态栏(QStatusBar)是 QMainWindow 提供的标准控件,用于帮助用户更好地与应用程序交互,所以本文给大家介绍了Python使用PyQt5实现与DeepSeek聊天的图形化小软件,需要的朋友可以参考下

1. 导入依赖库

import sys
import requests
import json
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QTextEdit, QLineEdit, QPushButton, QLabel, QFileDialog
from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5.QtGui import QPixmap
  • sys: 用于处理 Python 的系统相关功能,例如退出程序。
  • requests: 用于发送 HTTP 请求,与 DeepSeek API 进行通信。
  • json: 用于处理 JSON 格式的数据。
  • PyQt5: 用于创建图形用户界面(GUI)。
    • QApplication: 管理应用程序的控制流和主要设置。
    • QWidget: 所有用户界面对象的基类。
    • QVBoxLayout: 垂直布局管理器,用于排列控件。
    • QTextEdit: 多行文本输入框,用于显示聊天记录。
    • QLineEdit: 单行文本输入框,用于用户输入消息。
    • QPushButton: 按钮控件,用于触发事件。
    • QLabel: 标签控件,用于显示文本或图像。
    • QFileDialog: 文件选择对话框,用于上传图像。
  • QThread: 用于创建多线程,避免阻塞主线程。
  • pyqtSignal: 用于在线程和主线程之间传递信号。
  • QPixmap: 用于加载和显示图像。

2. DeepSeek API 配置

DEEPSEEK_API_URL = "https://api.deepseek.com/v1/chat/completions"
DEEPSEEK_API_KEY = "your_deepseek_api_key"  # 替换为自己的 DeepSeek API Key
  • DEEPSEEK_API_URL: DeepSeek API 的端点 URL。
  • DEEPSEEK_API_KEY: DeepSeek API 密钥,用于身份验证。

3. ChatThread 类

class ChatThread(QThread):
    response_received = pyqtSignal(str)
    stream_response_received = pyqtSignal(str)

    def __init__(self, messages, stream=False):
        super().__init__()
        self.messages = messages
        self.stream = stream

    def run(self):
        headers = {
            "Authorization": f"Bearer {DEEPSEEK_API_KEY}",
            "Content-Type": "application/json"
        }

        data = {
            "model": "deepseek-chat",
            "messages": self.messages,
            "stream": self.stream
        }

        if self.stream:
            response = requests.post(DEEPSEEK_API_URL, headers=headers, json=data, stream=True)
            for line in response.iter_lines():
                if line:
                    decoded_line = line.decode('utf-8')
                    if decoded_line.startswith("data:"):
                        json_data = json.loads(decoded_line[5:])
                        if "choices" in json_data:
                            content = json_data["choices"][0]["delta"].get("content", "")
                            self.stream_response_received.emit(content)
        else:
            response = requests.post(DEEPSEEK_API_URL, headers=headers, json=data)
            if response.status_code == 200:
                json_data = response.json()
                content = json_data["choices"][0]["message"]["content"]
                self.response_received.emit(content)
            else:
                self.response_received.emit("Error: 无法从DeepSeekAPI获得响应.")

功能说明

  • ChatThread 是一个继承自 QThread 的类,用于在后台与 DeepSeek API 进行通信。
  • response_received 和 stream_response_received: 这两个信号用于将 API 的响应传递回主线程。
  • __init__ 方法:
    • 接受 messages(聊天记录)和 stream(是否启用流式输出)作为参数。
  • run 方法:
    • 发送 HTTP POST 请求到 DeepSeek API。
    • 如果启用流式输出(stream=True),则逐行读取响应并发送信号。
    • 如果禁用流式输出,则等待完整响应后发送信号。

4. ChatApp 类

class ChatApp(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()
        self.messages = []

    def initUI(self):
        self.setWindowTitle('DeepSeek Chat')
        self.setGeometry(100, 100, 600, 400)

        layout = QVBoxLayout()

        self.chat_display = QTextEdit()
        self.chat_display.setReadOnly(True)
        layout.addWidget(self.chat_display)

        self.input_box = QLineEdit()
        self.input_box.setPlaceholderText("在此留下你的千言万语...")
        layout.addWidget(self.input_box)

        self.send_button = QPushButton('发送')
        self.send_button.clicked.connect(self.send_message)
        layout.addWidget(self.send_button)

        self.image_label = QLabel()
        layout.addWidget(self.image_label)

        self.upload_image_button = QPushButton('上传图片')
        self.upload_image_button.clicked.connect(self.upload_image)
        layout.addWidget(self.upload_image_button)

        self.setLayout(layout)

功能说明

  • ChatApp 是主应用程序类,继承自 QWidget
  • __init__ 方法:
    • 初始化界面并创建一个空的消息列表 self.messages
  • initUI 方法:
    • 设置窗口标题和大小。
    • 使用 QVBoxLayout 垂直排列控件。
    • chat_display: 用于显示聊天记录的多行文本框。
    • input_box: 用于用户输入消息的单行文本框。
    • send_button: 发送消息的按钮,点击后触发 send_message 方法。
    • image_label: 用于显示上传的图像。
    • upload_image_button: 上传图像的按钮,点击后触发 upload_image 方法。

5. 核心功能方法

5.1 send_message 方法

def send_message(self):
    user_input = self.input_box.text()
    if user_input:
        self.messages.append({"role": "user", "content": user_input})
        self.chat_display.append(f"You: {user_input}")
        self.input_box.clear()

        self.chat_thread = ChatThread(self.messages, stream=True)
        self.chat_thread.stream_response_received.connect(self.update_chat_display_stream)
        self.chat_thread.start()
  • 获取用户输入的消息。
  • 将消息添加到 self.messages 列表中。
  • 在聊天显示区域显示用户的消息。
  • 清空输入框。
  • 启动 ChatThread 线程与 DeepSeek API 通信,并启用流式输出。

5.2 update_chat_display_stream 方法

def update_chat_display_stream(self, content):
    self.chat_display.moveCursor(self.chat_display.textCursor().End)
    self.chat_display.insertPlainText(content)
    self.chat_display.moveCursor(self.chat_display.textCursor().End)
  • 将 DeepSeek API 的流式响应逐字添加到聊天显示区域。
  • 确保光标始终在文本末尾,以便用户可以看到最新的内容。

5.3 upload_image 方法

def upload_image(self):
    options = QFileDialog.Options()
    file_name, _ = QFileDialog.getOpenFileName(self, "上传图片", "", "Images (*.png *.jpg *.jpeg)", options=options)
    if file_name:
        pixmap = QPixmap(file_name)
        self.image_label.setPixmap(pixmap.scaled(200, 200))
        self.messages.append({"role": "user", "content": f"Image: {file_name}"})
  • 打开文件选择对话框,允许用户选择图像文件。
  • 加载图像并显示在 image_label 中。
  • 将图像路径添加到 self.messages 列表中。

6. 主程序入口

if __name__ == '__main__':
    app = QApplication(sys.argv)
    chat_app = ChatApp()
    chat_app.show()
    sys.exit(app.exec_())
  • 创建 QApplication 实例。
  • 创建 ChatApp 实例并显示窗口。
  • 进入主事件循环,等待用户交互。

7、完整代码如下:

需要安装PyQt5和requests

pip install PyQt5 requests
import sys
import requests
import json
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QTextEdit, QLineEdit, QPushButton, QLabel, QFileDialog
from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5.QtGui import QPixmap

# DeepSeek API 配置
DEEPSEEK_API_URL = "https://api.deepseek.com/v1/chat/completions"
DEEPSEEK_API_KEY = "your_deepseek_api_key"  # 替换为自己的 DeepSeek API Key,去DeepSeek注册获取

class ChatThread(QThread):
    response_received = pyqtSignal(str)
    stream_response_received = pyqtSignal(str)

    def __init__(self, messages, stream=False):
        super().__init__()
        self.messages = messages
        self.stream = stream

    def run(self):
        headers = {
            "Authorization": f"Bearer {DEEPSEEK_API_KEY}",
            "Content-Type": "application/json"
        }

        data = {
            "model": "deepseek-chat",
            "messages": self.messages,
            "stream": self.stream
        }

        if self.stream:
            response = requests.post(DEEPSEEK_API_URL, headers=headers, json=data, stream=True)
            for line in response.iter_lines():
                if line:
                    decoded_line = line.decode('utf-8')
                    if decoded_line.startswith("data:"):
                        json_data = json.loads(decoded_line[5:])
                        if "choices" in json_data:
                            content = json_data["choices"][0]["delta"].get("content", "")
                            self.stream_response_received.emit(content)
        else:
            response = requests.post(DEEPSEEK_API_URL, headers=headers, json=data)
            if response.status_code == 200:
                json_data = response.json()
                content = json_data["choices"][0]["message"]["content"]
                self.response_received.emit(content)
            else:
                self.response_received.emit("Error: 无法从DeepSeekAPI获得响应.")

class ChatApp(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()
        self.messages = []

    def initUI(self):
        self.setWindowTitle('DeepSeek Chat')
        self.setGeometry(100, 100, 600, 400)

        layout = QVBoxLayout()

        self.chat_display = QTextEdit()
        self.chat_display.setReadOnly(True)
        layout.addWidget(self.chat_display)

        self.input_box = QLineEdit()
        self.input_box.setPlaceholderText("在此留下你的千言万语...")
        layout.addWidget(self.input_box)

        self.send_button = QPushButton('发送')
        self.send_button.clicked.connect(self.send_message)
        layout.addWidget(self.send_button)

        self.image_label = QLabel()
        layout.addWidget(self.image_label)

        self.upload_image_button = QPushButton('上传图片')
        self.upload_image_button.clicked.connect(self.upload_image)
        layout.addWidget(self.upload_image_button)

        self.setLayout(layout)

    def send_message(self):
        user_input = self.input_box.text()
        if user_input:
            self.messages.append({"role": "user", "content": user_input})
            self.chat_display.append(f"You: {user_input}")
            self.input_box.clear()

            self.chat_thread = ChatThread(self.messages, stream=True)
            self.chat_thread.stream_response_received.connect(self.update_chat_display_stream)
            self.chat_thread.start()

    def update_chat_display_stream(self, content):
        self.chat_display.moveCursor(self.chat_display.textCursor().End)
        self.chat_display.insertPlainText(content)
        self.chat_display.moveCursor(self.chat_display.textCursor().End)

    def upload_image(self):
        options = QFileDialog.Options()
        file_name, _ = QFileDialog.getOpenFileName(self, "上传图片", "", "Images (*.png *.jpg *.jpeg)", options=options)
        if file_name:
            pixmap = QPixmap(file_name)
            self.image_label.setPixmap(pixmap.scaled(200, 200))
            self.messages.append({"role": "user", "content": f"Image: {file_name}"})

if __name__ == '__main__':
    app = QApplication(sys.argv)
    chat_app = ChatApp()
    chat_app.show()
    sys.exit(app.exec_())

8. 总结

  • 使用 PyQt5 创建了一个简单的图形化聊天界面。
  • 通过 ChatThread 实现了与 DeepSeek API 的异步通信,支持流式和非流式输出。
  • 支持多轮对话和多模态输入(如图像上传)。
  • 代码结构清晰,易于扩展和优化。

以上就是Python使用PyQt5实现与DeepSeek聊天的图形化小软件的详细内容,更多关于Python PyQt5与DeepSeek聊天软件的资料请关注脚本之家其它相关文章!

相关文章

  • Python批量实现word中查找关键字的示例代码

    Python批量实现word中查找关键字的示例代码

    本文主要介绍了Python批量实现word中查找关键字的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • windows支持哪个版本的python

    windows支持哪个版本的python

    在本篇文章中小编给大家分享了关于windows支持python的版本的相关内容知识点,需要的朋友们可以学习下。
    2020-07-07
  • 快速进修Python指南之控制if-else循环技巧

    快速进修Python指南之控制if-else循环技巧

    这篇文章主要为大家介绍了Java开发者的Python快速进修指南之控制之if-else和循环技巧示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • Python Selenium防检测策略汇总

    Python Selenium防检测策略汇总

    这篇文章主要为大家详细介绍了Python Selenium防检测的一些策略汇总,文中的示例代码简洁易懂,有需要的小伙伴可以根据自己的需要进行选择
    2025-04-04
  • 使用Python实现音频双通道分离

    使用Python实现音频双通道分离

    这篇文章主要介绍了使用Python实现音频双通道分离的方法,帮助大家更好的理解和使用python,感兴趣的朋友可以了解下
    2020-12-12
  • Centos安装python3与scapy模块的问题及解决方法

    Centos安装python3与scapy模块的问题及解决方法

    这篇文章主要介绍了Centos安装python3与scapy模块的问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-07-07
  • 2021年最新用于图像处理的Python库总结

    2021年最新用于图像处理的Python库总结

    为了快速地处理大量信息,科学家需要利用图像准备工具来完成人工智能和深度学习任务.在本文中,我将深入研究Python中最有用的图像处理库,这些库正在人工智能和深度学习任务中得到大力利用.我们开始吧,需要的朋友可以参考下
    2021-06-06
  • Python使用Seaborn快速生成高颜值业务图表

    Python使用Seaborn快速生成高颜值业务图表

    本文介绍了Python数据可视化库Seaborn的核心功能与应用场景,掌握Seaborn与Matplotlib的关系,学习使用Seaborn美化图表绘制各类分布图、分类图、回归图和配对图,提升数据可视化能力,需要的朋友可以参考下
    2026-06-06
  • 基于python编写图片高斯模糊处理脚本

    基于python编写图片高斯模糊处理脚本

    gaussian_blur.py是一个基于 Python 的图片处理脚本,使用 Pillow 库对图片应用高斯模糊效果,支持自定义模糊强度,下面小编就和大家详细介绍一下具体的实现步骤吧
    2026-03-03
  • Python强大的自省机制详解

    Python强大的自省机制详解

    这篇文章主要为大家介绍了Python强大的自省机制,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2021-11-11

最新评论