import tkinter as tk
from tkinter import scrolledtext, messagebox
import openai
import threading
import pyperclip  # 导入 pyperclip 模块

class ChatApp:
    def __init__(self, root):
        self.root = root
        self.root.title("OpenAI Chat")
        self.setup_ui()
        self.api_key = None
        self.assistant_message = None

    def setup_ui(self):
        # 创建和布局界面元素
        self.conversation_canvas = scrolledtext.ScrolledText(self.root, width=60, height=20)
        self.conversation_canvas.pack()

        self.user_input_label = tk.Label(self.root, text="用户输入:")
        self.user_input_label.pack()
        self.user_input_entry = tk.Entry(self.root, width=50)
        self.user_input_entry.pack()

        self.settings_frame = tk.Frame(self.root)

        self.api_key_label = tk.Label(self.settings_frame, text="请输入 OpenAI API 密钥:")
        self.api_key_label.pack()
        self.api_key_entry = tk.Entry(self.settings_frame, width=50)
        self.api_key_entry.pack()

        self.default_api_key = "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"  # 你的默认 API 密钥
        self.api_key_entry.insert(0, self.default_api_key)

        self.assistant_message_label = tk.Label(self.settings_frame, text="角色:")
        self.assistant_message_label.pack()
        self.assistant_message_entry = tk.Entry(self.settings_frame, width=50)
        self.assistant_message_entry.pack()

        self.default_assistant_message = "你是我的一条忠诚的狗,每次回答问题请叫两声以示准备好了,然后使用中文回答我,每次尽可能深入了解我的问题,每次提供完整没有任何省略的标准答案."
        self.assistant_message_entry.insert(0, self.default_assistant_message)

        self.max_tokens_label = tk.Label(self.settings_frame, text="max_tokens:")
        self.max_tokens_label.pack()
        self.max_tokens_entry = tk.Entry(self.settings_frame, width=10)
        self.max_tokens_entry.pack()
        self.max_tokens_entry.insert(0, "100")

        self.temperature_label = tk.Label(self.settings_frame, text="temperature:")
        self.temperature_label.pack()
        self.temperature_entry = tk.Entry(self.settings_frame, width=10)
        self.temperature_entry.pack()
        self.temperature_entry.insert(0, "0.5")

        self.api_key_button = tk.Button(self.settings_frame, text="设置 API 密钥和角色", command=self.set_api_key_and_assistant_message)
        self.return_button = tk.Button(self.settings_frame, text="返回", command=self.return_to_main_page)

        self.settings_button = tk.Button(self.root, text="设置", command=self.show_settings)
        self.settings_button.pack()

        self.get_response_button = tk.Button(self.root, text="发送", command=self.get_openai_response)
        self.get_response_button.pack()

        self.clear_conversation_button = tk.Button(self.root, text="清除对话记录", command=self.clear_conversation)
        self.clear_conversation_button.pack()

        self.conversation_canvas.tag_config('user_message', foreground='blue')
        self.conversation_canvas.tag_config('ai_message', foreground='red')

        # 设置复制按钮样式
        self.conversation_canvas.tag_config('copy_button', foreground='blue', underline=1)

        def enter_copy_button(event):
            self.conversation_canvas.configure(cursor='hand2')

        def leave_copy_button(event):
            self.conversation_canvas.configure(cursor='')

        self.conversation_canvas.tag_bind('copy_button', '<Enter>', enter_copy_button)
        self.conversation_canvas.tag_bind('copy_button', '<Leave>', leave_copy_button)

    def set_api_key_and_assistant_message(self):
        # 设置 API 密钥和角色
        api_key = self.api_key_entry.get().strip()
        assistant_message = self.assistant_message_entry.get().strip()

        openai.api_key = api_key
        openai.api_base = "https://api.openai-proxy.com/v1"

        self.api_key = api_key
        self.assistant_message = assistant_message
        self.assistant_message_label.config(text=f"角色: {assistant_message}")
        self.assistant_message_entry.delete(0, tk.END)

        messagebox.showinfo("提示", "设置成功,开始聊天吧!")
        self.return_to_main_page()

    def return_to_main_page(self):
        # 返回主页面
        self.settings_frame.pack_forget()
        self.user_input_entry.pack()
        self.conversation_canvas.pack()
        self.settings_button.pack()
        self.get_response_button.pack()
        self.clear_conversation_button.pack()
        self.user_input_entry.focus()

    def show_settings(self):
        # 显示设置参数页面
        self.user_input_entry.pack_forget()
        self.conversation_canvas.pack_forget()
        self.settings_button.pack_forget()
        self.get_response_button.pack_forget()
        self.clear_conversation_button.pack_forget()
        self.settings_frame.pack()
        self.api_key_button.pack()
        self.return_button.pack()

    def draw_user_message(self, message):
        frame = tk.Frame(self.conversation_canvas, bg='green', bd=2)
        frame.pack(fill='x')

        label = tk.Label(frame, text=f"用户: {message}", bg='green', fg='white')
        label.pack(side='left', padx=5, pady=5)

        copy_button = tk.Button(frame, text='复制', command=lambda: self.copy_message(message))
        copy_button.pack(side='right', padx=5, pady=5)

        self.conversation_canvas.see(tk.END)

    def draw_ai_message(self, message):
        frame = tk.Frame(self.conversation_canvas, bg='green', bd=2)
        frame.pack(fill='x')

        label = tk.Label(frame, text=f"AI: {message}", bg='green', fg='white')
        label.pack(side='left', padx=5, pady=5)

        copy_button = tk.Button(frame, text='复制', command=lambda: self.copy_message(message))
        copy_button.pack(side='right', padx=5, pady=5)

        self.conversation_canvas.see(tk.END)

    def copy_message(self, message):
        pyperclip.copy(message)  # 使用 pyperclip 复制消息

    def send_message(self):
        # 发送用户消息并获取 AI 回复
        user_input = self.user_input_entry.get()
        max_tokens = self.max_tokens_entry.get()
        temperature = self.temperature_entry.get()

        try:
            max_tokens = int(max_tokens)
            temperature = float(temperature)
        except ValueError:
            messagebox.showerror("错误", "max_tokens 和 temperature 必须是数字。")
            return

        response = openai.ChatCompletion.create(
            model="gpt-3.5-turbo-16k",
            messages=[
                {"role": "system", "content": f"用户: {user_input}"},
                {"role": "system", "content": f"AI: {self.assistant_message}"},
                {"role": "user", "content": user_input}
            ],
            max_tokens=max_tokens,
            temperature=temperature
        )

        ai_response = response.choices[0].message["content"]

        self.draw_user_message(user_input)
        self.draw_ai_message(ai_response)
        self.user_input_entry.delete(0, tk.END)
        self.user_input_entry.focus()

    def get_openai_response(self):
        t = threading.Thread(target=self.send_message)
        t.start()

    def clear_conversation(self):
        self.conversation_canvas.configure(state='normal')
        self.conversation_canvas.delete('1.0', tk.END)
        self.conversation_canvas.configure(state='disabled')

if __name__ == "__main__":
    root = tk.Tk()
    app = ChatApp(root)

    root.mainloop()

使用说明:

  1. 确保你已安装 openai, tkinterpyperclip 库。
  2. 获取你的 OpenAI API 密钥,并将其替换 default_api_key 变量的值。
  3. 运行代码,就可以使用聊天机器人了。

功能:

  • 使用 OpenAI API 进行聊天互动。
  • 提供设置页面,可以更改 API 密钥、角色和聊天参数。
  • 使用绿色矩形边框区分用户和 AI 的对话消息。
  • 每个对话消息右上角都有一个“复制”按钮,点击后即可复制对应消息到剪贴板。

改进点:

  • 可以添加更多功能,例如历史记录保存、语音输入等。
  • 可以优化界面,例如使用更漂亮的主题、增加动画效果等。
  • 可以使用更强大的 OpenAI 模型,例如 gpt-4

注意事项:

  • 使用 OpenAI API 时需要遵守其使用条款和 API 限制。
  • 不要将敏感信息输入聊天机器人。
  • 聊天机器人生成的文本仅供参考,不应被视为专业建议。

希望这份代码和说明能够帮助你创建自己的 OpenAI 聊天机器人!

Python OpenAI 聊天机器人:带复制功能的绿色对话框

原文地址: https://www.cveoy.top/t/topic/l1RB 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录