在Python中调用API创建AI聊天窗口,核心是将图形用户界面(GUI)与AI模型的HTTP API调用相结合,实现用户输入、API请求、响应展示的完整闭环。以下是两种主流、可立即运行的实现方案,涵盖从环境搭建到代码部署的全过程。

一、 方案对比与选型指南

在开始编码前,可根据下表选择最适合你需求的技术栈:

特性维度 方案一:Tkinter + 通用API 方案二:PySimpleGUI + 官方SDK 方案三:本地模型 + 轻量GUI
GUI库 Tkinter (Python内置) PySimpleGUI (基于Tkinter封装) 任选 (Tkinter/PySimpleGUI)
API调用方式 requests 库发送HTTP请求 使用模型提供的官方Python SDK 调用本地部署模型的API (如Ollama)
优点 无需额外安装GUI库,控制粒度细,学习资源丰富 代码更简洁,布局更直观,开发速度快 完全离线,数据隐私性强,无网络延迟
缺点 原生API较底层,复杂布局代码量多 需额外安装PySimpleGUI 需本地部署模型,消耗计算资源
适用场景 希望深入理解底层机制的教学或原型项目 追求开发效率的快速应用搭建 对数据隐私有严格要求或网络不便的环境

二、 方案一详解:使用Tkinter与requests调用智谱AI API

此方案使用Python标准库,适合希望掌握每个步骤细节的开发者。

1. 环境准备与依赖安装

# 安装HTTP请求库
pip install requests

关键步骤:前往智谱AI开放平台注册并创建应用,获取你的API Key

2. 完整可运行代码

创建一个名为ai_chat_tkinter.py的文件,粘贴以下代码并替换your_api_key_here为你的真实密钥。

import tkinter as tk
from tkinter import scrolledtext, messagebox, END
import requests
import json
import threading
from datetime import datetime

class AIChatApp:
    def __init__(self, root):
        self.root = root
        self.root.title("智谱AI聊天助手 - Tkinter版")
        self.root.geometry("750x850")
        
        # ========== 1. API配置 ==========
        self.api_key = "your_api_key_here"  # 请在此处替换为你的API Key 
        self.api_url = "https://open.bigmodel.cn/api/paas/v4/chat/completions"
        self.model = "glm-4-flash"  # 可选模型: glm-4, glm-4-plus, glm-3-turbo
        self.max_tokens = 1024
        
        # ========== 2. 初始化对话历史 ==========
        self.conversation_history = [
            {"role": "system", "content": "你是一个专业、友好且乐于助人的AI助手。"}
        ]
        
        # ========== 3. 创建GUI界面组件 ==========
        self.setup_ui()
        
    def setup_ui(self):
        """构建用户界面"""
        # 主框架:采用网格布局
        main_frame = tk.Frame(self.root, padx=15, pady=15)
        main_frame.pack(fill=tk.BOTH, expand=True)
        
        # 3.1 标题标签
        title_label = tk.Label(
            main_frame, 
            text="💬 AI 对话助手", 
            font=("微软雅黑", 16, "bold"),
            fg="#2c3e50"
        )
        title_label.grid(row=0, column=0, columnspan=2, pady=(0, 15))
        
        # 3.2 聊天历史显示区域(带滚动条)
        history_frame = tk.LabelFrame(main_frame, text="对话历史", padx=10, pady=10)
        history_frame.grid(row=1, column=0, columnspan=2, sticky="nsew", pady=(0, 15))
        
        # 配置网格权重,使聊天区域可伸缩
        main_frame.grid_rowconfigure(1, weight=1)
        main_frame.grid_columnconfigure(0, weight=1)
        main_frame.grid_columnconfigure(1, weight=1)
        
        self.chat_display = scrolledtext.ScrolledText(
            history_frame, 
            wrap=tk.WORD, 
            width=80, 
            height=25,
            font=("宋体", 11),
            state='normal'
        )
        self.chat_display.pack(fill=tk.BOTH, expand=True)
        self.chat_display.tag_config("user", foreground="blue", font=("宋体", 11, "bold"))
        self.chat_display.tag_config("ai", foreground="green", font=("宋体", 11))
        self.chat_display.tag_config("error", foreground="red")
        
        # 3.3 输入控件框架
        input_frame = tk.Frame(main_frame)
        input_frame.grid(row=2, column=0, columnspan=2, sticky="ew", pady=(10, 0))
        
        # 输入提示
        input_label = tk.Label(input_frame, text="请输入您的问题:")
        input_label.pack(anchor="w", pady=(0, 5))
        
        # 多行输入文本框
        self.input_text = scrolledtext.ScrolledText(
            input_frame, 
            height=4,
            wrap=tk.WORD,
            font=("宋体", 11)
        )
        self.input_text.pack(fill=tk.X, pady=(0, 10))
        self.input_text.bind("<Control-Return>", self.on_ctrl_enter)  # 绑定Ctrl+Enter快捷发送
        
        # 3.4 按钮框架
        button_frame = tk.Frame(input_frame)
        button_frame.pack(fill=tk.X)
        
        send_btn = tk.Button(
            button_frame, 
            text="发送 (Ctrl+Enter)", 
            command=self.send_message,
            bg="#3498db",
            fg="white",
            font=("微软雅黑", 10),
            padx=20,
            pady=5
        )
        send_btn.pack(side=tk.LEFT, padx=(0, 10))
        
        clear_btn = tk.Button(
            button_frame,
            text="清空对话",
            command=self.clear_conversation,
            bg="#e74c3c",
            fg="white",
            font=("微软雅黑", 10),
            padx=20,
            pady=5
        )
        clear_btn.pack(side=tk.LEFT)
        
        # 3.5 状态栏
        self.status_var = tk.StringVar(value="✅ 就绪")
        status_bar = tk.Label(
            self.root, 
            textvariable=self.status_var,
            bd=1, 
            relief=tk.SUNKEN, 
            anchor=tk.W,
            bg="#f0f0f0"
        )
        status_bar.pack(side=tk.BOTTOM, fill=tk.X)
        
    def on_ctrl_enter(self, event):
        """处理Ctrl+Enter快捷键发送"""
        self.send_message()
        return "break"  # 阻止默认换行行为
        
    def send_message(self):
        """处理发送消息的核心逻辑"""
        # 获取并预处理用户输入
        user_input = self.input_text.get("1.0", END).strip()
        if not user_input:
            messagebox.showwarning("输入为空", "请输入内容后再发送。")
            return
            
        # 1. 清空输入框并更新状态
        self.input_text.delete("1.0", END)
        self.status_var.set("⏳ AI正在思考...")
        self.root.update()
        
        # 2. 在聊天区域显示用户消息
        timestamp = datetime.now().strftime("%H:%M:%S")
        self.append_to_chat(f"[{timestamp}] 你:
", "user")
        self.append_to_chat(f"{user_input}

")
        
        # 3. 在新线程中调用API,避免界面冻结
        thread = threading.Thread(target=self.process_ai_response, args=(user_input,))
        thread.daemon = True
        thread.start()
        
    def process_ai_response(self, user_input):
        """在后台线程中处理API调用"""
        try:
            # 调用AI模型API
            ai_response = self.call_ai_api(user_input)
            
            # 在主线程中更新GUI
            self.root.after(0, self.display_ai_response, ai_response)
            
        except Exception as e:
            error_msg = f"请求出错:{str(e)}"
            self.root.after(0, self.display_error, error_msg)
            
    def call_ai_api(self, user_message):
        """调用智谱AI ChatCompletion API"""
        # 1. 准备请求头
        headers = {
            "Authorization": f"Bearer {self.api_key}",
            "Content-Type": "application/json"
        }
        
        # 2. 更新对话历史
        self.conversation_history.append({"role": "user", "content": user_message})
        
        # 3. 构建请求体
        payload = {
            "model": self.model,
            "messages": self.conversation_history,
            "temperature": 0.7,  # 控制回复随机性 (0.0-1.0)
            "max_tokens": self.max_tokens,
            "stream": False
        }
        
        # 4. 发送POST请求
        response = requests.post(
            self.api_url, 
            headers=headers, 
            json=payload, 
            timeout=30  # 设置超时时间
        )
        response.raise_for_status()  # 如果状态码不是200,抛出异常
        
        # 5. 解析响应
        result = response.json()
        ai_reply = result["choices"][0]["message"]["content"]
        
        # 6. 保存到对话历史
        self.conversation_history.append({"role": "assistant", "content": ai_reply})
        
        return ai_reply
        
    def display_ai_response(self, response_text):
        """在主线程中安全地显示AI回复"""
        timestamp = datetime.now().strftime("%H:%M:%S")
        self.append_to_chat(f"[{timestamp}] AI:
", "ai")
        self.append_to_chat(f"{response_text}
{'='*60}

")
        self.status_var.set("✅ 就绪")
        
    def display_error(self, error_text):
        """显示错误信息"""
        self.append_to_chat(f"❌ 错误:{error_text}

", "error")
        self.status_var.set("❌ 发生错误")
        
    def append_to_chat(self, text, tag=None):
        """向聊天区域追加文本"""
        self.chat_display.configure(state='normal')
        if tag:
            self.chat_display.insert(END, text, tag)
        else:
            self.chat_display.insert(END, text)
        self.chat_display.configure(state='disabled')
        self.chat_display.see(END)  # 自动滚动到底部
        
    def clear_conversation(self):
        """清空当前对话"""
        if messagebox.askyesno("确认清空", "确定要清空对话历史吗?"):
            self.chat_display.configure(state='normal')
            self.chat_display.delete("1.0", END)
            self.chat_display.configure(state='disabled')
            # 重置对话历史,但保留系统提示
            self.conversation_history = self.conversation_history[:1]
            self.status_var.set("✅ 对话已清空")

# 程序入口
if __name__ == "__main__":
    root = tk.Tk()
    app = AIChatApp(root)
    
    # 窗口居中显示
    root.update_idletasks()
    width = root.winfo_width()
    height = root.winfo_height()
    x = (root.winfo_screenwidth() // 2) - (width // 2)
    y = (root.winfo_screenheight() // 2) - (height // 2)
    root.geometry(f'{width}x{height}+{x}+{y}')
    
    root.mainloop()

3. 代码核心解析

  • 多线程处理:通过threading.Thread将耗时的网络请求放入后台线程,确保GUI界面在等待API响应时不会卡死。
  • 线程安全更新:所有对GUI组件的修改(如append_to_chat)都通过root.after(0, ...)在主线程中执行,这是Tkinter多线程编程的最佳实践。
  • 上下文管理self.conversation_history列表完整保存了对话的上下文,每次API调用都将其传入,使AI能理解之前的对话内容,实现真正的多轮对话。
  • 错误处理:通过try-except块捕获网络异常和API错误,并通过状态栏和颜色标签给予用户明确反馈。

三、 方案二详解:使用PySimpleGUI与DeepSeek官方SDK

此方案使用更高级的GUI库和官方SDK,代码更简洁,适合快速开发。

1. 环境准备

# 安装PySimpleGUI和DeepSeek官方SDK
pip install PySimpleGUI openai

注意:DeepSeek API与OpenAI API兼容,因此可以使用openai这个官方库。前往DeepSeek平台获取API Key。

2. 完整可运行代码

创建ai_chat_pysimplegui.py文件,替换your_deepseek_api_key_here

import PySimpleGUI as sg
import openai  # DeepSeek兼容OpenAI SDK
import threading
import json
from datetime import datetime
import os

# 设置GUI主题
sg.theme('LightBlue3')
sg.set_options(font=("Microsoft YaHei", 10))

class DeepSeekChatApp:
    def __init__(self):
        # ========== 1. 初始化DeepSeek客户端 ==========
        self.client = openai.OpenAI(
            api_key="your_deepseek_api_key_here",  # 替换为你的DeepSeek API Key 
            base_url="https://api.deepseek.com"  # DeepSeek API端点
        )
        
        # ========== 2. 对话历史与配置 ==========
        self.messages = [
            {"role": "system", "content": "You are DeepSeek AI, a helpful assistant."}
        ]
        self.model = "deepseek-chat"  # 可选: deepseek-coder, deepseek-reasoner
        self.max_history = 10  # 保留最近10轮对话(防止上下文过长)
        
        # ========== 3. 创建主窗口 ==========
        self.window = self.create_main_window()
        
    def create_main_window(self):
        """使用PySimpleGUI创建主窗口布局"""
        # 左侧聊天历史区域
        chat_history_column = [
            [sg.Text("💭 DeepSeek AI 对话助手", font=("Microsoft YaHei", 14, "bold"))],
            [sg.Multiline(
                size=(70, 30),
                key="-CHAT_HISTORY-",
                autoscroll=True,
                disabled=True,
                background_color="#FAFAFA",
                text_color="#333333",
                font=("Consolas", 10)
            )],
            [sg.Text("当前模型: "), 
             sg.Combo(["deepseek-chat", "deepseek-coder"], 
                     default_value="deepseek-chat",
                     key="-MODEL-",
                     enable_events=True,
                     readonly=True)]
        ]
        
        # 右侧控制面板
        control_panel_column = [
            [sg.Text("对话控制", font=("Microsoft YaHei", 12, "bold"))],
            [sg.Button("导出对话", key="-EXPORT-", size=(12, 1))],
            [sg.Button("导入对话", key="-IMPORT-", size=(12, 1))],
            [sg.Button("清空历史", key="-CLEAR-", size=(12, 1), button_color=("white", "red"))],
            [sg.HorizontalSeparator()],
            [sg.Text("参数设置", font=("Microsoft YaHei", 12, "bold"))],
            [sg.Text("温度 (0.0-2.0):")],
            [sg.Slider(range=(0.0, 2.0), 
                      default_value=0.7, 
                      resolution=0.1,
                      orientation='h',
                      key="-TEMPERATURE-",
                      size=(20, 15))],
            [sg.Text("最大生成长度:")],
            [sg.Input(default_text="1024", key="-MAX_TOKENS-", size=(10, 1))],
            [sg.HorizontalSeparator()],
            [sg.Text("会话信息", font=("Microsoft YaHei", 10))],
            [sg.Multiline("对话已就绪...
", 
                         size=(30, 5), 
                         key="-STATUS-",
                         disabled=True,
                         autoscroll=True)]
        ]
        
        # 底部输入区域
        input_area = [
            [sg.Multiline(
                size=(85, 4),
                key="-USER_INPUT-",
                enter_submits=False,  # 禁用回车提交,改用Ctrl+Enter
                tooltip="输入消息,按 Ctrl+Enter 发送",
                font=("Microsoft YaHei", 11)
            )],
            [sg.Button("发送 (Ctrl+Enter)", key="-SEND-", size=(15, 1), button_color=("white", "#4CAF50")),
             sg.Button("退出", key="-EXIT-", size=(10

----

## 参考来源
- [python调用火山引擎大模型实现人工智能语音聊天机器人](https://blog.csdn.net/xingdiango/article/details/148231867)
- [Python调用智谱API实现简单AI对话框](https://blog.csdn.net/qq_68076599/article/details/143243079)
- [《AI大模型趣味实战》教10岁儿童使用Python调用智谱AI大模型创建图形化AI聊天机器人的教程](https://blog.csdn.net/yweng18/article/details/147477146)
- [[AI]从零开始的DeepSeek本地部署及本地API调用教程](https://blog.csdn.net/c858845275/article/details/145544208)
- [Python调用DeepSeek API实现图形化窗口](https://blog.csdn.net/aaaa11111112/article/details/146115612)
- [调用蓝耘Maas平台大模型API打造个人AI助理实战](https://blog.csdn.net/2301_80840905/article/details/148317768)

 

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐