You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

153 lines
5.3 KiB

import tkinter as tk
import customtkinter as ctk
class ChatComponent:
"""聊天界面组件"""
def __init__(self, parent_frame, app):
self.parent_frame = parent_frame
self.app = app
self.api = app.api # 从app实例获取api
self.chat_area = None
self.chat_scrollable_frame = None
self.input_frame = None
self.user_input = None
self.clear_btn = None
self.send_btn = None
self._create_chat_interface()
def _create_chat_interface(self):
"""创建聊天界面"""
# 创建聊天区域
self.chat_area = ctk.CTkFrame(self.parent_frame, fg_color="#1e1e1e")
# 1. 顶部标题栏
header_frame = ctk.CTkFrame(self.chat_area, fg_color="#252525", corner_radius=10)
header_frame.pack(fill="x", pady=(0, 10), padx=5)
# 标题
title_label = ctk.CTkLabel(
header_frame,
text="DeepSeek AI Assistant",
font=ctk.CTkFont(family="Microsoft YaHei UI", size=20, weight="bold"),
text_color="#ffffff"
)
title_label.pack(side="left", padx=20, pady=15)
# 模型选择
self.model_var = tk.StringVar(value=self.api.model)
self.model_combo = ctk.CTkComboBox(
header_frame,
variable=self.model_var,
values=["deepseek-chat", "deepseek-coder"],
width=150,
corner_radius=8,
fg_color="#333333",
button_color="#444444",
button_hover_color="#555555"
)
self.model_combo.pack(side="right", padx=(5, 5), pady=15, anchor="e")
model_label = ctk.CTkLabel(header_frame, text="模型:", text_color="#cccccc")
model_label.pack(side="right", padx=(5, 20), pady=15, anchor="e")
# 2. 聊天消息区域
chat_container = ctk.CTkFrame(self.chat_area, fg_color="#1e1e1e", corner_radius=10)
chat_container.pack(fill="both", expand=True, padx=5, pady=(0, 10))
self.chat_scrollable_frame = ctk.CTkScrollableFrame(
chat_container,
fg_color="#1e1e1e",
scrollbar_button_color="#333333",
scrollbar_button_hover_color="#444444"
)
self.chat_scrollable_frame.pack(fill="both", expand=True, padx=10, pady=10)
# 3. 底部输入区域
self.input_frame = ctk.CTkFrame(self.chat_area, fg_color="#252525", corner_radius=10)
self.input_frame.pack(fill="x", padx=5, pady=(0, 5))
self.input_frame.columnconfigure(0, weight=1)
self.input_frame.columnconfigure(1, minsize=80)
self.input_frame.columnconfigure(2, minsize=60)
self.input_frame.rowconfigure(0, weight=1)
# 输入框
self.user_input = ctk.CTkEntry(
self.input_frame,
placeholder_text="输入您的问题...",
height=40,
corner_radius=20,
fg_color="#333333",
text_color="#ffffff",
placeholder_text_color="#999999"
)
self.user_input.grid(row=0, column=0, padx=15, pady=15, sticky="ew")
# 清空按钮
self.clear_btn = ctk.CTkButton(
self.input_frame,
text="清空",
width=60,
height=40,
corner_radius=20,
fg_color="#F7DC6F",
hover_color="#F1C40F"
)
self.clear_btn.grid(row=0, column=1, padx=(0, 5), pady=15, sticky="ew")
# 发送按钮
self.send_btn = ctk.CTkButton(
self.input_frame,
text="发送",
width=80,
height=40,
corner_radius=20,
fg_color="#005a9e",
hover_color="#004a80"
)
self.send_btn.grid(row=0, column=2, padx=15, pady=15, sticky="ew")
def get_chat_area(self):
"""获取聊天区域"""
return self.chat_area
def get_chat_scrollable_frame(self):
"""获取聊天滚动区域"""
return self.chat_scrollable_frame
def get_user_input(self):
"""获取用户输入框"""
return self.user_input
def get_model_var(self):
"""获取模型变量"""
return self.model_var
def get_model_combo(self):
"""获取模型选择下拉框"""
return self.model_combo
def get_clear_btn(self):
"""获取清空按钮"""
return self.clear_btn
def get_send_btn(self):
"""获取发送按钮"""
return self.send_btn
def show(self):
"""显示聊天界面"""
self.chat_area.pack(side="right", fill="both", expand=True, padx=(0, 5))
def bind_events(self, send_message_callback, clear_chat_callback, on_model_change_callback, insert_newline_callback):
"""绑定事件"""
self.send_btn.configure(command=send_message_callback)
self.user_input.bind("<Return>", lambda e: send_message_callback())
self.user_input.bind("<Shift-Return>", lambda e: insert_newline_callback())
self.model_combo.configure(command=on_model_change_callback)
self.clear_btn.configure(command=clear_chat_callback)
def hide(self):
"""隐藏聊天界面"""
self.chat_area.pack_forget()